﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<NDepend AppName="Apache.Ignite" Platform="DotNet" FileWrittenByProductVersion="2017.2.2.8962">
  <OutputDir KeepXmlFiles="False">c:\w\incubator-ignite\modules\platforms\dotnet\NDependOut</OutputDir>
  <Assemblies>
    <Name>Apache.Ignite.Core</Name>
  </Assemblies>
  <FrameworkAssemblies>
    <Name>mscorlib</Name>
    <Name>System.Core</Name>
    <Name>System.Xml</Name>
    <Name>System</Name>
    <Name>System.Configuration</Name>
    <Name>System.Transactions</Name>
  </FrameworkAssemblies>
  <Dirs>
    <Dir>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319</Dir>
    <Dir>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\WPF</Dir>
    <Dir>$(NdProjectDir)\Apache.Ignite.Core\bin\Debug</Dir>
  </Dirs>
  <MergeCodeGeneratedByCompiler>True</MergeCodeGeneratedByCompiler>
  <Report Kind="0" SectionsEnabled="110591" XslPath="" Flags="261120" />
  <BuildComparisonSetting ProjectMode="CurrentProject" BuildMode="NDaysAgoAnalysisResult" ProjectFileToCompareWith="" BuildFileToCompareWith="" NDaysAgo="30" />
  <BaselineInUISetting ProjectMode="CurrentProject" BuildMode="NDaysAgoAnalysisResult" ProjectFileToCompareWith="" BuildFileToCompareWith="" NDaysAgo="30" />
  <CoverageFiles CoverageDir="" UncoverableAttribute="" />
  <TrendMetrics UseCustomLog="False" LogRecurrence="3" LogLabel="2" UseCustomDir="False" CustomDir="">
    <Chart Name="Size" ShowInReport="True">
      <Serie MetricName="# Lines of Code" MetricUnit="Loc" Color="#FF00BFFF" ChartType="Line" ScaleExp="0" />
      <Serie MetricName="# Lines of Code Covered" MetricUnit="Loc" Color="#FF32CD32" ChartType="Area" ScaleExp="0" />
      <Serie MetricName="# Lines of Code (NotMyCode)" MetricUnit="Loc" Color="#FFA9A9A9" ChartType="Area" ScaleExp="0" />
      <Serie MetricName="# Lines of Comments" MetricUnit="Lines" Color="#FF008000" ChartType="Line" ScaleExp="0" />
    </Chart>
    <Chart Name="% Coverage and % Debt" ShowInReport="True">
      <Serie MetricName="Percentage Code Coverage" MetricUnit="%" Color="#FF32CD32" ChartType="Area" ScaleExp="0" />
      <Serie MetricName="Percentage Debt (Metric)" MetricUnit="%" Color="#FFFF0000" ChartType="Line" ScaleExp="0" />
    </Chart>
    <Chart Name="Issues" ShowInReport="True">
      <Serie MetricName="# New Issues since Baseline" MetricUnit="issues" Color="#FFFF0000" ChartType="Line" ScaleExp="0" />
      <Serie MetricName="# Issues Fixed since Baseline" MetricUnit="issues" Color="#FF32CD32" ChartType="Line" ScaleExp="0" />
      <Serie MetricName="# Blocker/Critical/Major Issues" MetricUnit="issues" Color="#FFFF8C00" ChartType="Line" ScaleExp="0" />
      <Serie MetricName="# Issues" MetricUnit="issues" Color="#FFFFD700" ChartType="Line" ScaleExp="-2" />
    </Chart>
    <Chart Name="Rules" ShowInReport="True">
      <Serie MetricName="# Rules" MetricUnit="Rules" Color="#FF66CDAA" ChartType="Line" ScaleExp="0" />
      <Serie MetricName="# Rules Violated" MetricUnit="Rules" Color="#FFFF8C00" ChartType="Area" ScaleExp="0" />
      <Serie MetricName="# Critical Rules Violated" MetricUnit="Rules" Color="#FFFF0000" ChartType="Area" ScaleExp="0" />
    </Chart>
    <Chart Name="Quality Gates" ShowInReport="True">
      <Serie MetricName="# Quality Gates Fail" MetricUnit="quality gates" Color="#FFFF0000" ChartType="Line" ScaleExp="0" />
      <Serie MetricName="# Quality Gates Warn" MetricUnit="quality gates" Color="#FFFF8C00" ChartType="Line" ScaleExp="0" />
      <Serie MetricName="# Quality Gates" MetricUnit="quality gates" Color="#FF32CD32" ChartType="Line" ScaleExp="0" />
    </Chart>
    <Chart Name="Debt" ShowInReport="True">
      <Serie MetricName="Debt (Metric)" MetricUnit="man-days" Color="#FFFF0000" ChartType="Line" ScaleExp="0" />
      <Serie MetricName="Annual Interest (Metric)" MetricUnit="man-days" Color="#FFFF8C00" ChartType="Line" ScaleExp="0" />
    </Chart>
  </TrendMetrics>
  <HistoricAnalysisResult PersistRecurrence="3" UseCustomDir="False" CustomDir="" />
  <SourceFileRebasing FromPath="" ToPath="" />
  <PathVariables />
  <RuleFiles />
  <ProjectRules AreActive="True" />
  <ProjectDebtSettings DebtSettingsStorage="0" SettingsFilePath="">
    <DebtSettings>
      <DebtFactor>1</DebtFactor>
      <AnnualInterestFactor>1</AnnualInterestFactor>
      <DebtDefault>0</DebtDefault>
      <AnnualInterestDefault>0</AnnualInterestDefault>
      <DebtStringFormat>$ManDay$</DebtStringFormat>
      <MoneyPerManHour>50</MoneyPerManHour>
      <Currency>USD</Currency>
      <CurrencyLocation>After</CurrencyLocation>
      <EstimatedNumberOfManDayToDevelop1000LogicalLinesOfCode>18</EstimatedNumberOfManDayToDevelop1000LogicalLinesOfCode>
      <NumberOfWorkDayPerYear>240</NumberOfWorkDayPerYear>
      <NumberOfWorkHourPerDay>8</NumberOfWorkHourPerDay>
      <A2B_RatingThreshold>5</A2B_RatingThreshold>
      <B2C_RatingThreshold>10</B2C_RatingThreshold>
      <C2D_RatingThreshold>20</C2D_RatingThreshold>
      <D2E_RatingThreshold>50</D2E_RatingThreshold>
      <Low2Medium_SeverityThreshold>1200000000</Low2Medium_SeverityThreshold>
      <Medium2High_SeverityThreshold>12000000000</Medium2High_SeverityThreshold>
      <High2Critical_SeverityThreshold>72000000000</High2Critical_SeverityThreshold>
      <Critical2Blocker_SeverityThreshold>360000000000</Critical2Blocker_SeverityThreshold>
    </DebtSettings>
  </ProjectDebtSettings>
  <Queries>
    <Group Name="Quality Gates" Active="True" ShownInReport="True">
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Quality Gates Evolution</Name>
from qg in QualityGates
let qgBaseline = qg.OlderVersion()
let relyOnDiff = qgBaseline == null
let evolution = relyOnDiff ? (TrendIcon?)null : 
                // When a quality gate relies on diff between now and baseline
                // it is not executed against the baseline
                qg.ValueDiff() == 0d ?
                TrendIcon.Constant :
                (qg.ValueDiff() > 0 ? 
                  ( qg.MoreIsBad ?  TrendIcon.RedUp: TrendIcon.GreenUp) :
                  (!qg.MoreIsBad ?  TrendIcon.RedDown: TrendIcon.GreenDown))
select new { qg, 
   Evolution      =  evolution,

   BaselineStatus =  relyOnDiff? (QualityGateStatus?) null : qgBaseline.Status,
   Status         =  qg.Status,

   BaselineValue  =  relyOnDiff? (null) : qgBaseline.ValueString,
   Value          =  qg.ValueString, 
}
 
// <Description>
// Show quality gates evolution between baseline and now.
//
// When a quality gate relies on diff between now and baseline (like *New Debt since Baseline*)
// it is not executed against the baseline and as a consequence its evolution is not available.
//
// Double-click a quality gate for editing.
// </Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Percentage Coverage" Unit="%" />
failif value < 70%
warnif value < 80%
codeBase.PercentageCoverage

//<Description>
// Code coverage is a measure used to describe the degree to which the source code of a program 
// is tested by a particular test suite. A program with high code coverage, measured as a percentage, 
// has had more of its source code executed during testing which suggests it has a lower chance of 
// containing undetected software bugs compared to a program with low code coverage.
//
// Code coverage is certainly the most important quality code metric. But coverage is not enough
// the team needs to ensure that results are checked at test-time. These checks can be done both 
// in test code, and in application code through assertions. The important part is that a test
// must fail explicitely when a check gets unvalidated during the test execution.
//
// This quality gate define a warn threshold (70%) and a fail threshold (80%). These are 
// indicative thresholds and in practice the more the better. To achieve high coverage and 
// low risk, make sure that new and refactored classes gets 100% covered by tests and that
// the application and test code contains as many checks/assertions as possible.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Percentage Coverage on New Code" Unit="%" />
failif value < 70%
warnif value < 80%
let newMethods = Application.Methods.Where(m => m.WasAdded() && m.NbLinesOfCode > 0)
let locCovered = newMethods.Sum(m => m.NbLinesOfCodeCovered)
let loc = newMethods.Sum(m => m.NbLinesOfCode)
select 100d * locCovered / loc

//<Description>
// *New Code* is defined as methods added since the baseline.
//
// To achieve high code coverage it is essential that new code gets properly
// tested and covered by tests. It is advised that all non-UI new classes gets
// 100% covered.
//
// Typically 90% of a class is easy to cover by tests and 10% is hard to reach 
// through tests. It means that this 10% remaining is not easily testable, which 
// means it is not well designed, which often means that this code is especially 
// **error-prone**. This is the reason why it is important to reach 100% coverage
// for a class, to make sure that potentially *error-prone* code gets tested.
//</Description>
]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Percentage Coverage on Refactored Code" Unit="%" />
failif value < 70%
warnif value < 80%
let newMethods = Application.Methods.Where(m => m.CodeWasChanged() && m.NbLinesOfCode > 0)
let locCovered = newMethods.Sum(m => m.NbLinesOfCodeCovered)
let loc = newMethods.Sum(m => m.NbLinesOfCode)
select 100d * locCovered / loc

//<Description>
// *Refactored Code* is defined as methods where *code was changed* since the baseline.
//
// Comment changes and formatting changes are not considerd as refactoring.
//
// To achieve high code coverage it is essential that refactored code gets properly
// tested and covered by tests. It is advised that when refactoring a class
// or a method, it is important to also write tests to make sure it gets 100% covered.
//
// Typically 90% of a class is easy to cover by tests and 10% is hard to reach 
// through tests. It means that this 10% remaining is not easily testable, which 
// means it is not well designed, which often means that this code is especially 
// **error-prone**. This is the reason why it is important to reach 100% coverage
// for a class, to make sure that potentially *error-prone* code gets tested.
//</Description>
]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Blocker Issues" Unit="issues" />
failif count > 0 issues
from i in Issues
where i.Severity == Severity.Blocker
select new { i, i.Severity, i.Debt, i.AnnualInterest }

//<Description>
// An issue with the severity **Blocker** cannot move to production, it must be fixed.
//
// The severity of an issue is either defined explicitely in the rule source code,
// either inferred from the issue *annual interest* and thresholds defined in the 
// NDepend Project Properties > Issue and Debt.
//</Description>

]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Critical Issues" Unit="issues" />
failif count > 10 issues
warnif count > 0 issues

from i in Issues
where i.Severity == Severity.Critical
select new { i, i.Severity, i.Debt, i.AnnualInterest }

//<Description>
// An issue with a severity level **Critical** shouldn't move to production. 
// It still can for business imperative needs purposes, but at worst it must 
// be fixed during the next iterations. 
//
// The severity of an issue is either defined explicitely in the rule source code,
// either inferred from the issue *annual interest* and thresholds defined in the 
// NDepend Project Properties > Issue and Debt.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="New Blocker / Critical / High Issues" Unit="issues" />
failif count > 0 issues
from i in Issues
where i.Severity.EqualsAny(Severity.Blocker, Severity.Critical, Severity.High) &&  
      // Count both the new issues and the issues that became at least Critical
      (i.WasAdded() || i.OlderVersion().Severity < Severity.High)
select new { i, i.Severity, i.Debt, i.AnnualInterest }


//<Description>
// An issue with the severity **Blocker** cannot move to production, it must be fixed.
//
// An issue with a severity level **Critical** shouldn't move to production. 
// It still can for business imperative needs purposes, but at worth it must be fixed 
// during the next iterations. 
//
// An issue with a severity level **High** should be fixed quickly, but can wait until 
// the next scheduled interval.
//
// The severity of an issue is either defined explicitely in the rule source code,
// either inferred from the issue *annual interest* and thresholds defined in the 
// NDepend Project Properties > Issue and Debt.
//</Description>
]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Critical Rules Violated" Unit="rules" />
failif count > 0 rules
from r in Rules where r.IsCritical && r.IsViolated()
select new { r, issues = r.Issues() }

//<Description>
// The concept of critical rule is useful to pinpoint certain rules that 
// should not be violated.
//
// A rule can be made critical just by checking the *Critical button* in the
// rule edition control and then saving the rule.
//
// This quality gate fails if any critical rule gets any violations.
//
// When no baseline is available, rules that rely on diff are not counted.
// If you observe that this quality gate count slightly decreases with no apparent reason,
// the reason is certainly that rules that rely on diff are not counted
// because the baseline is not defined.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Percentage Debt" Unit="%" />
failif value > 30%
warnif value > 20%
let timeToDev = codeBase.EffortToDevelop()
let debt = Issues.Sum(i => i.Debt)
select 100d * debt.ToManDay() / timeToDev.ToManDay()

// <Description>
// % Debt total is defined as a percentage on:
//
// • the estimated total effort to develop the code base
//
// • and the the estimated total time to fix all issues (the Debt)
//
// Estimated total effort to develop the code base is inferred from 
// # lines of code of the code base and from the 
// *Estimated number of man-day to develop 1000 logicial lines of code*
// setting found in NDepend Project Properties > Issue and Debt.
//
// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
//
// This quality gates fails if the estimated debt is more than 30%
// of the estimated effort to develop the code base, and warns if the 
// estimated debt is more than 20% of the estimated effort to develop 
// the code base
// </Description>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Debt" Unit="man-days" />
failif value > 50 man-days
warnif value > 30 man-days
Issues.Sum(i => i.Debt).ToManDay()

//<Description>
// This Quality Gate is disabled per default because the fail and warn 
// thresholds of unacceptable Debt in man-days can only depend on the 
// project size, number of developers and overall context.
//
// However you can refer to the default Quality Gate **Percentage Debt**.
//
// The Debt is defined as the sum of estimated effort to fix all issues.
// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="New Debt since Baseline" Unit="man-days" />
failif value > 2 man-days
warnif value > 0 man-days
let debt = Issues.Sum(i => i.Debt)
let debtInBaseline = IssuesInBaseline.Sum(i => i.Debt)
select (debt - debtInBaseline).ToManDay()


//<Description>
// This Quality Gate fails if the estimated effort to fix new or worsened
// issues (what is called the *New Debt since Baseline*) is higher
// than 2 man-days.
//
// This Quality Gate warns if this estimated effort is positive.
//
// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Debt Rating per Namespace" Unit="namespaces" />
failif count > 0 namespaces

from n in Application.Namespaces
where n.DebtRating() != null &&
      n.DebtRating().Value.EqualsAny(DebtRating.E, DebtRating.D)
select new { 
   n, 
   debtRating = n.DebtRating(),
   debtRatio = n.DebtRatio(),  // % of debt from which DebtRating is inferred
   devTimeInManDay = n.EffortToDevelop().ToDebt(), 
   debtInManDay = n.AllDebt(),
   issues = n.AllIssues() 
}

// <Description>
// Forbid namespaces with a poor Debt Rating equals to **E** or **D**.
//
// The **Debt Rating** for a code element is estimated by the value of the **Debt Ratio**
// and from the various rating thresholds defined in this project *Debt Settings*. 
//
// The **Debt Ratio** of a code element is a percentage of **Debt Amount** (in floating man-days) 
// compared to the **estimated effort to develop the code element** (also in floating man-days).
//
// The **estimated effort to develop the code element** is inferred from the code elements
// number of lines of code, and from the project *Debt Settings* parameters 
// *estimated number of man-days to develop 1000* **logical lines of code**.
//
// The **logical lines of code** corresponds to the number of debug breakpoints in a method
// and doesn't depend on code formatting nor comments.
//
// The Quality Gate can be modified to match assemblies, types or methods
// with a poor Debt Rating, instead of matching namespaces.
// </Description>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Annual Interest" Unit="man-days" />
failif value > 50 man-days
warnif value > 30 man-days
Issues.Sum(i => i.AnnualInterest).ToManDay()


//<Description>
// This Quality Gate is disabled per default because the fail and warn 
// thresholds of unacceptable Annual-Interest in man-days can only depend
// on the project size, number of developers and overall context.
//
// However you can refer to the default Quality Gate 
// **New Annual Interest since Baseline**.
//
// The Annual-Interest is defined as the sum of estimated annual cost
// in man-days, to leave all issues unfixed.
//
// Each rule can either provide a formula to compute the Annual-Interest 
// per issue, or assign a **Severity** level for each issue. Some thresholds
// defined in *Project Properties > Issue and Debt > Annual Interest* are
// used to infer an Annual-Interest value from a Severity level.
// Annual Interest documentation: http://www.ndepend.com/docs/technical-debt#AnnualInterest
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="New Annual Interest since Baseline" Unit="man-days" />
failif value > 2 man-days
warnif value > 0 man-days
let ai = Issues.Sum(i => i.AnnualInterest)
let aiInBaseline = IssuesInBaseline.Sum(i => i.AnnualInterest)
select (ai - aiInBaseline).ToManDay()

//<Description>
// This Quality Gate fails if the estimated annual cost to leave all issues
// unfixed, increased from more than 2 man-days since the baseline.
//
// This Quality Gate warns if this estimated annual cost is positive.
//
// This estimated annual cost is named the **Annual-Interest**.
//
// Each rule can either provide a formula to compute the Annual-Interest 
// per issue, or assign a **Severity** level for each issue. Some thresholds
// defined in *Project Properties > Issue and Debt > Annual Interest* are
// used to infer an Annual-Interest value from a Severity level.
// Annual Interest documentation: http://www.ndepend.com/docs/technical-debt#AnnualInterest
//</Description>]]></Query>
    </Group>
    <Group Name="Hot Spots" Active="True" ShownInReport="True">
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types Hot Spots</Name>
from t in JustMyCode.Types
where t.AllDebt() > Debt.Zero && 
      t.AllAnnualInterest() > AnnualInterest.Zero
orderby t.AllDebt().Value.TotalMinutes descending
select new { t, 
   Debt = t.AllDebt(),
   Issues = t.AllIssues(), // AllIssues = {types issues} union {members issues}
   AnnualInterest = t.AllAnnualInterest(),
   BreakingPoint = t.AllBreakingPoint(),
   t.NbLinesOfCode,
   // t.PercentageCoverage,  to uncomment if coverage data is imported
   DebtRating = t.DebtRating(), 
   DebtRatio = t.DebtRatio() 
}

//<Description>
// This query lists **types with most Debt**,
// or in other words, types with issues that would need 
// the largest effort to get fixed.
//
// Both issues on the type and its members are
// taken account.
//
// Since untested code often generates a lot of 
// Debt, the type size and percentage coverage is shown
// (just uncomment *t.PercentageCoverage* in the query 
// source code once you've imported the coverage data).
//
// The *Debt Rating* and *Debt Ratio* are also shown
// for informational purpose.
//
// --
//
// The amount of *Debt* is not a measure to prioritize
// the effort to fix issues, it is an estimation of how far 
// the team is from clean code that abides by the rules set.
//
// For each issue the *Annual Interest* estimates the annual 
// cost to leave the issues unfixed. The *Severity* of an issue
// is estimated through thresholds from the *Annual Interest*.
//
// The **Debt Breaking Point** represents the duration
// from now when the estimated cost to leave the issue unfixed
// costs as much as the estimated effort to fix it.
//
// Hence the shorter the **Debt Breaking Point** 
// the largest the **Return on Investment** for fixing 
// the issue. The **Breaking Point is the right metric
// to prioritize issues fix**.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types to Fix Priority</Name>
from t in JustMyCode.Types
where t.AllBreakingPoint() > TimeSpan.Zero &&
      t.AllDebt().Value > 30.ToMinutes()
orderby t.AllBreakingPoint().TotalMinutes ascending
select new { t, 
   BreakingPoint = t.AllBreakingPoint(),
   Debt = t.AllDebt(),
   AnnualInterest = t.AllAnnualInterest(),
   Issues = t.AllIssues(),
   t.NbLinesOfCode,
   // t.PercentageCoverage,  to uncomment if coverage data is imported
   DebtRating = t.DebtRating(), 
   DebtRatio = t.DebtRatio() 
}

//<Description>
// This query lists types per increasing
// **Debt Breaking Point**.
//
// For each issue the *Debt* estimates the
// effort to fix the issue, and the *Annual Interest*
// estimates the annual cost to leave the issue unfixed.
// The *Severity* of an issue is estimated through 
// thresholds from the *Annual Interest* of the issue.
//
// The **Debt Breaking Point** represents the duration
// from now when the estimated cost to leave the issue unfixed
// costs as much as the estimated effort to fix it.
//
// Hence the shorter the **Debt Breaking Point** 
// the largest the **Return on Investment** for fixing 
// the issues.
//
// Often new and refactored types since baseline will be 
// listed first, because issues on these types get a 
// higher *Annual Interest* because it is important to
// focus first on new issues.
// 
//
// --
//
// Both issues on the type and its members are
// taken account.
//
// Only types with at least 30 minutes of Debt are listed
// to avoid parasiting the list with the numerous
// types with small *Debt*, on which the *Breaking Point*
// value makes less sense. 
//
// The *Annual Interest* estimates the cost per year
// in man-days to leave these issues unfixed.
//
// Since untested code often generates a lot of 
// Debt, the type size and percentage coverage is shown
// (just uncomment *t.PercentageCoverage* in the query 
// source code once you've imported the coverage data).
//
// The *Debt Rating* and *Debt Ratio* are also shown
// for informational purpose.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Issues to Fix Priority</Name>
from i in Issues
// Don't show first issues with BreakingPoint equals to zero.
orderby i.BreakingPoint != TimeSpan.Zero ? i.BreakingPoint : TimeSpan.MaxValue
select new { i, 
   Debt = i.Debt,
   AnnualInterest = i.AnnualInterest,
   BreakingPoint = i.BreakingPoint,
   CodeElement = i.CodeElement
}

//<Description>
// This query lists issues per increasing
// **Debt Breaking Point**.
//
// Double-click an issue to edit its rule and
// select the issue in the rule result. This way
// you can view all information concerning the issue.
//
// For each issue the *Debt* estimates the
// effort to fix the issue, and the *Annual Interest*
// estimates the annual cost to leave the issue unfixed.
// The *Severity* of an issue is estimated through 
// thresholds from the *Annual Interest* of the issue.
//
// The **Debt Breaking Point** represents the duration
// from now when the estimated cost to leave the issue unfixed
// costs as much as the estimated effort to fix it.
//
// Hence the shorter the **Debt Breaking Point** 
// the largest the **Return on Investment** for fixing 
// the issue.
//
// Often issues on new and refactored code elements since 
// baseline will be listed first, because such issues get a 
// higher *Annual Interest* because it is important to
// focus first on new issues on recent code.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Debt and Issues per Rule</Name>
from r in Rules
where r.IsViolated()
orderby r.Debt().Value descending
select new { 
   r, 
   Issues = r.Issues(), 
   Debt = r.Debt(), 
   AnnualInterest = r.AnnualInterest(), 
   BreakingPoint = r.BreakingPoint(),
   Category = r.Category
}

//<Description>
// This query lists violated rules with most *Debt* first.
//
// A rule violated has issues. For each issue the *Debt* 
// estimates the effort to fix the issue.
//
// --
//
// The amount of *Debt* is not a measure to prioritize
// the effort to fix issues, it is an estimation of how far 
// the team is from clean code that abides by the rules set.
//
// For each issue the *Annual Interest* estimates the annual 
// cost to leave the issues unfixed. The *Severity* of an issue
// is estimated through thresholds from the *Annual Interest*.
//
// The **Debt Breaking Point** represents the duration
// from now when the estimated cost to leave the issue unfixed
// costs as much as the estimated effort to fix it.
//
// Hence the shorter the **Debt Breaking Point** 
// the largest the **Return on Investment** for fixing 
// the issue. The **Breaking Point is the right metric
// to prioritize issues fix**.
//
// --
//
// Notice that rules can be grouped in *Rule Category*. This
// way you'll see categories that generate most *Debt*.
//
// Typically the rules that generate most *Debt* are the 
// ones related to *Code Coverage by Tests*, *Architecture*
// and *Code Smells*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New Debt and Issues per Rule</Name>
from r in Rules
where r.IsViolated() && r.IssuesAdded().Count() > 0
orderby r.DebtDiff().Value descending
select new { 
   r, 
   IssuesAdded = r.IssuesAdded(),
   IssuesFixed = r.IssuesFixed(),
   Issues = r.Issues(), 
   Debt = r.Debt(), 
   DebtDiff = r.DebtDiff(),
   Category = r.Category
}

//<Description>
// This query lists violated rules that have new issues
// since baseline, with most **new Debt** first.
//
// A rule violated has issues. For each issue the *Debt* 
// estimates the effort to fix the issue.
//
// --
//
// New issues since the baseline are consequence of recent code 
// refactoring sessions. They represent good opportunities
// of fix because the code recently refactored is fresh in 
// the developers mind, which means fixing now costs less
// than fixing later.
//
// Fixing issues on recently touched code is also a good way 
// to foster practices that will lead to higher code quality 
// and maintainability, including writing unit-tests
// and avoiding unnecessary complex code.
//
// --
//
// Notice that rules can be grouped in *Rule Category*. This
// way you'll see categories that generate most *Debt*.
//
// Typically the rules that generate most *Debt* are the 
// ones related to *Code Coverage by Tests*, *Architecture*
// and *Code Smells*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Debt and Issues per Code Element</Name>
from elem in CodeElements
where elem.HasIssue()
orderby elem.Debt().Value descending
select new { 
   elem, 
   Issues = elem.Issues(), 
   Debt = elem.Debt(), 
   AnnualInterest = elem.AnnualInterest(), 
   BreakingPoint = elem.BreakingPoint()
}

//<Description>
// This query lists code elements that have issues, 
// with most *Debt* first.
//
// For each code element the *Debt* estimates 
// the effort to fix the element issues.
//
// The amount of *Debt* is not a measure to prioritize
// the effort to fix issues, it is an estimation of how far 
// the team is from clean code that abides by the rules set.
//
// For each element the *Annual Interest* estimates the annual 
// cost to leave the elements issues unfixed. The *Severity* of an 
// issue is estimated through thresholds from the *Annual Interest*
// of the issue.
//
// The **Debt Breaking Point** represents the duration
// from now when the estimated cost to leave the issues unfixed
// costs as much as the estimated effort to fix it.
//
// Hence the shorter the **Debt Breaking Point** 
// the largest the **Return on Investment** for fixing 
// the issue. The **Breaking Point is the right metric
// to prioritize issues fix**.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New Debt and Issues per Code Element</Name>
from elem in CodeElements
where elem.HasIssue() && elem.IssuesAdded().Count() > 0
orderby elem.DebtDiff().Value descending
select new { 
   elem, 
   IssuesAdded = elem.IssuesAdded(),
   IssuesFixed = elem.IssuesFixed(),
   Issues = elem.Issues(), 
   Debt = elem.Debt(), 
   DebtDiff = elem.DebtDiff()
}
    //<Description>
// This query lists code elements that have new issues
// since baseline, with most **new Debt** first.
//
// For each code element the *Debt* estimates 
// the effort to fix the element issues.
//
// New issues since the baseline are consequence of recent code 
// refactoring sessions. They represent good opportunities
// of fix because the code recently refactored is fresh in 
// the developers mind, which means fixing now costs less
// than fixing later.
//
// Fixing issues on recently touched code is also a good way 
// to foster practices that will lead to higher code quality 
// and maintainability, including writing unit-tests
// and avoiding unnecessary complex code.
//</Description>
]]></Query>
    </Group>
    <Group Name="Code Smells" Active="True" ShownInReport="False">
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid types too big</Name>
warnif count > 0 from t in JustMyCode.Types where 

   // First filter on type to optimize 
   t.NbLinesOfCode > 200 
   // # IL Instructions is commented, because with LINQ syntax, a few lines of code can compile to hundreds of IL instructions.
   // || t.NbILInstructions > 3000

   // What matters is the # lines of code in JustMyCode
   let locJustMyCode = t.MethodsAndContructors.Where(m => JustMyCode.Contains(m)).Sum(m => m.NbLinesOfCode)
   where locJustMyCode > 200

   let isStaticWithNoMutableState = (t.IsStatic && t.Fields.Any(f => !f.IsImmutable))
   let staticFactor = (isStaticWithNoMutableState ? 0.2 : 1)

   orderby locJustMyCode descending
select new { 
   t, 
   locJustMyCode, 
   t.NbILInstructions,
   t.Methods, 
   t.Fields,
   
   Debt = (staticFactor*locJustMyCode.Linear(200, 1, 2000, 10)).ToHours().ToDebt(),

   // The annual interest varies linearly from interest for severity major for 300 loc
   // to interest for severity critical for 2000 loc
   AnnualInterest = staticFactor*(locJustMyCode.Linear(
                          200,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
                          2000, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
}

//<Description>
// This rule matches types with more than 200 lines of code.
// **Only lines of code in JustMyCode methods are taken account.**
//
// Types where *NbLinesOfCode > 200* are extremely complex 
// to develop and maintain.
// See the definition of the NbLinesOfCode metric here 
// http://www.ndepend.com/docs/code-metrics#NbLinesOfCode
//
// Maybe you are facing the **God Class** phenomenon:
// A **God Class** is a class that controls way too many other classes 
// in the system and has grown beyond all logic to become 
// *The Class That Does Everything*.
//</Description>

//<HowToFix>
// Types with many lines of code
// should be split in a group of smaller types.
// 
// To refactor a *God Class* you'll need patience, 
// and you might even need to recreate everything from scratch.
// Here are a few refactoring advices:
//
// • The logic in the *God Class* must be splitted in smaller classes.
// These smaller classes can eventually become private classes nested
// in the original *God Class*, whose instances objects become 
// composed of instances of smaller nested classes.
//
// • Smaller classes partitioning should be driven by the multiple
// responsibilities handled by the *God Class*. To identify these 
// responsibilities it often helps to look for subsets of methods
// strongly coupled with subsets of fields.
//
// • If the *God Class* contains way more logic than states, a good 
// option can be to define one or several static classes that 
// contains no static field but only pure static methods. A pure static 
// method is a function that computes a result only from inputs
// parameters, it doesn't read nor assign any static or instance field.
// The main advantage of pure static methods is that they are easily
// testable.
// 
// • Try to maintain the interface of the *God Class* at first 
// and delegate calls to the new extracted classes. 
// In the end the *God Class* should be a pure facade without its own logic.
// Then you can keep it for convenience or throw it away and 
// start to use the new classes only.
//
// • Unit Tests can help: write tests for each method before extracting it 
// to ensure you don't break functionality.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 1 hour for a 200 lines of code type,
// up to 10 hours for a type with 2.000 or more lines of code.
//
// In Debt and Interest computation, this rule takes account of the fact 
// that static types with no mutable fields are just a collection of 
// static methods that can be easily splitted and moved from one type 
// to another.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid types with too many methods</Name>
warnif count > 0 from t in JustMyCode.Types 

  // Optimization: Fast discard of non-relevant types 
  where t.Methods.Count() > 20

  // Don't match these methods
  let methods = t.Methods.Where(
       m => !(m.IsGeneratedByCompiler ||
              m.IsConstructor || m.IsClassConstructor ||
              m.IsPropertyGetter || m.IsPropertySetter ||
              m.IsEventAdder || m.IsEventRemover))

  where methods.Count() > 20 
  orderby methods.Count() descending

  let isStaticWithNoMutableState = (t.IsStatic && t.Fields.Any(f => !f.IsImmutable))
  let staticFactor = (isStaticWithNoMutableState ? 0.2 : 1)

select new { 
   t, 
   nbMethods = methods.Count(),
   instanceMethods = methods.Where(m => !m.IsStatic), 
   staticMethods = methods.Where(m => m.IsStatic),

   t.NbLinesOfCode,

   Debt = (staticFactor*methods.Count().Linear(20, 1, 200, 10)).ToHours().ToDebt(),

   // The annual interest varies linearly from interest for severity major for 30 methods
   // to interest for severity critical for 200 methods
   AnnualInterest = (staticFactor*methods.Count().Linear(
                              20,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
                              200, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
}

//<Description>
// This rule matches types with more than 20 methods. 
// Such type might be hard to understand and maintain.
//
// Notice that methods like constructors or property 
// and event accessors are not taken account.
//
// Having many methods for a type might be a symptom
// of too many responsibilities implemented.
//
// Maybe you are facing the **God Class** phenomenon:
// A **God Class** is a class that controls way too many other classes 
// in the system and has grown beyond all logic to become 
// *The Class That Does Everything*.
//</Description>

//<HowToFix>
// To refactor properly a *God Class* please read *HowToFix advices* 
// from the default rule **Types to Big**.
////
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 1 hour for a type with 20 methods,
// up to 10 hours for a type with 200 or more methods.
//
// In Debt and Interest computation, this rule takes account of the fact 
// that static types with no mutable fields are just a collection of 
// static methods that can be easily splitted and moved from one type 
// to another.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid types with too many fields</Name>
warnif count > 0 from t in JustMyCode.Types 

  // Optimization: Fast discard of non-relevant types 
  where !t.IsEnumeration &&
         t.Fields.Count() > 15
        
  // Count instance fields and non-constant static fields
  let fields = t.Fields.Where(f =>
          !f.IsGeneratedByCompiler &&
          !f.IsLiteral &&
          !(f.IsStatic && f.IsInitOnly) &&
           JustMyCode.Contains(f) )

  where fields.Count() > 15
 
  let methodsAssigningFields = fields.SelectMany(f => f.MethodsAssigningMe)

  orderby fields.Count() descending
select new { 
   t, 
   instanceFields = fields.Where(f => !f.IsStatic),
   staticFields = fields.Where(f => f.IsStatic),
methodsAssigningFields ,   

   // See definition of Size of Instances metric here:
   // http://www.ndepend.com/docs/code-metrics#SizeOfInst
   t.SizeOfInst,

   Debt = fields.Count().Linear(15, 1, 200, 10).ToHours().ToDebt(),

   // The annual interest varies linearly from interest for severity major for 30 methods
   // to interest for severity critical for 200 methods
   AnnualInterest = fields.Count().Linear(15,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
                                          200, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()
}

//<Description>
// This rule matches types with more than 15 fields. 
// Such type might be hard to understand and maintain.
//
// Notice that constant fields and static-readonly fields are not counted.
// Enumerations types are not counted also.
//
// Having many fields for a type might be a symptom
// of too many responsibilities implemented.
//</Description>

//<HowToFix>
// To refactor such type and increase code quality and maintainability,
// certainly you'll have to group subsets of fields into smaller types
// and dispatch the logic implemented into the methods 
// into these smaller types.
//
// More refactoring advices can be found in the default rule 
// **Types to Big**, *HowToFix* section.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 1 hour for a type with 15 fields,
// to up to 10 hours for a type with 200 or more fields. 
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid methods too big, too complex</Name>
warnif count > 0 from m in JustMyCode.Methods where 
   m.ILNestingDepth > 2 &&
  (m.NbLinesOfCode > 35 ||
   m.CyclomaticComplexity > 20 ||
   m.ILCyclomaticComplexity > 60)

  let complexityScore = m.NbLinesOfCode/2 + m.CyclomaticComplexity + m.ILCyclomaticComplexity/3 + 3*m.ILNestingDepth

  orderby complexityScore descending,
          m.CyclomaticComplexity descending,
          m.ILCyclomaticComplexity descending,
          m.ILNestingDepth descending
select new { 
   m, 
   m.NbLinesOfCode,
   m.CyclomaticComplexity, 
   m.ILCyclomaticComplexity,
   m.ILNestingDepth,
   complexityScore,

   Debt = complexityScore.Linear(30, 40,    400, 8*60).ToMinutes().ToDebt(),

   // The annual interest varies linearly from interest for severity minor 
   // to interest for severity major
   AnnualInterest = complexityScore .Linear(30,     Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
                                            200, 2*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
   
}

//<Description>
// This rule matches methods where *ILNestingDepth* > 2
// and (*NbLinesOfCode* > 35 
// or *CyclomaticComplexity* > 20
// or *ILCyclomaticComplexity* > 60)
// Such method is typically hard to understand and maintain.
//
// Maybe you are facing the **God Method** phenomenon.
// A "God Method" is a method that does way too many processes in the system 
// and has grown beyond all logic to become *The Method That Does Everything*.
// When need for new processes increases suddenly some programmers realize: 
// why should I create a new method for each processe if I can only add an *if*.
//
// See the definition of the *CyclomaticComplexity* metric here:
// http://www.ndepend.com/docs/code-metrics#CC
//
// See the definition of the *ILCyclomaticComplexity* metric here:
// http://www.ndepend.com/docs/code-metrics#ILCC
//
// See the definition of the *ILNestingDepth* metric here:
// http://www.ndepend.com/docs/code-metrics#ILNestingDepth
//</Description>

//<HowToFix>
// A large and complex method should be split in smaller methods, 
// or even one or several classes can be created for that.
//
// During this process it is important to question the scope of each
// variable local to the method. This can be an indication if
// such local variable will become an instance field of the newly created class(es).
//
// Large *switch…case* structures might be refactored through the help
// of a set of types that implement a common interface, the interface polymorphism
// playing the role of the *switch cases tests*.
//
// Unit Tests can help: write tests for each method before extracting it 
// to ensure you don't break functionality.
//
// The estimated Debt, which means the effort to fix such issue,
// varies from 40 minutes to 8 hours, linearly from a weighted complexity score.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid methods with too many parameters</Name>
warnif count > 0 from m in JustMyCode.Methods where 
  m.NbParameters >= 7
  orderby m.NbParameters descending
select new { 
   m, 
   m.NbParameters,

   Debt = m.NbParameters.Linear(7, 1,  40, 6).ToHours().ToDebt(),

   // The annual interest varies linearly from interest for severity Medium for 7 parameters
   // to interest for severity Critical for 40 parameters
   AnnualInterest = m.NbParameters.Linear(7,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
                                          40, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()
}

//<Description>
// This rule matches methods with more than 8 parameters.
// Such method is painful to call and might degrade performance.
// See the definition of the *NbParameters* metric here: 
// http://www.ndepend.com/docs/code-metrics#NbParameters
//</Description>

//<HowToFix>
// More properties/fields can be added to the declaring type to 
// handle numerous states. An alternative is to provide 
// a class or a structure dedicated to handle arguments passing.
// For example see the class *System.Diagnostics.ProcessStartInfo* 
// and the method *System.Diagnostics.Process.Start(ProcessStartInfo)*.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 1 hour for a method with 7 parameters,
// up to 6 hours for a methods with 40 or more parameters.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid methods with too many local variables</Name>
warnif count > 0 from m in JustMyCode.Methods where 
  m.NbVariables > 15 
  orderby m.NbVariables descending
select new { 
   m, 
   m.NbVariables,

   Debt = m.NbVariables.Linear(15, 1,   80, 6).ToHours().ToDebt(),

   // The annual interest varies linearly from interest for severity Medium for 15 variables
   // to interest for severity Critical for 80 variables
   AnnualInterest = m.NbVariables.Linear(15,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
                                         80,  Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()

}

//<Description>
// This rule matches methods with more than 15 variables.
//
// Methods where *NbVariables > 8* are hard to understand and maintain.
// Methods where *NbVariables > 15* are extremely complex and must be refactored. 
//
// See the definition of the *Nbvariables* metric here: 
// http://www.ndepend.com/docs/code-metrics#Nbvariables
//</Description>

//<HowToFix>
// To refactor such method and increase code quality and maintainability,
// certainly you'll have to split the method into several smaller methods
// or even create one or several classes to implement the logic.
//
// During this process it is important to question the scope of each
// variable local to the method. This can be an indication if
// such local variable will become an instance field of the newly created class(es).
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 10 minutes for a method with 15 variables,
// up to 2 hours for a methods with 80 or more variables.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid methods with too many overloads</Name>
warnif count > 0 

let lookup = JustMyCode.Methods.Where(m =>
   m.NbOverloads >= 6 && 
  !m.IsOperator && // Don't report operator overload

   // Don't match overloads due tu the visitor pattern, based on a naming convention.
  !m.SimpleName.ToLower().StartsWithAny("visit", "dispatch")
).ToLookup(m => m.ParentType.FullName + "."+ m.SimpleName)

from @group in lookup
let overloads = @group.ToArray()
orderby overloads.Length descending

select new { 
   m = @group.First(), 
   overloads,
   Debt = (3*overloads.Length).ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Method overloading is the ability to create multiple methods of the same name 
// with different implementations, and various set of parameters.
//
// This rule matches sets of methods with 6 overloads or more.
//
// Such method set might be a problem to maintain 
// and provokes coupling higher than necessary.
//
// See the definition of the *NbOverloads* metric here 
// http://www.ndepend.com/docs/code-metrics#NbOverloads
//</Description>

//<HowToFix>
// Typically the *too many overloads* phenomenon appears when an algorithm
// takes a various set of in-parameters. Each overload is presented as 
// a facility to provide a various set of in-parameters.
// In such situation, the C# and VB.NET language feature named 
// *Named and Optional arguments* should be used.
//
// The *too many overloads* phenomenon can also be a consequence of the usage
// of the **visitor design pattern** http://en.wikipedia.org/wiki/Visitor_pattern 
// since a method named *Visit()* must be provided for each sub type.
// For this reason, the default version of this rule doesn't match overloads whose name
// start with "visit" or "dispatch" (case-unsensitive) to avoid match 
// overload visitors, and you can adapt this rule to your own naming convention.
//
// Sometime *too many overloads* phenomenon is not the symptom of a problem,
// for example when a *numeric to something conversion* method applies to 
// all numeric and nullable numeric types.
//
// The estimated Debt, which means the effort to fix such issue,
// is of 3 minutes per method overload.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid methods potentially poorly commented</Name>
warnif count > 0 from m in JustMyCode.Methods where 
  m.PercentageComment < 10 && 
  m.NbLinesOfCode > 20  

  let nbLinesOfCodeNotCommented = m.NbLinesOfCode - m.NbLinesOfComment

  orderby nbLinesOfCodeNotCommented descending

select new { 
   m, 
   m.PercentageComment, 
   m.NbLinesOfCode, 
   m.NbLinesOfComment,
   nbLinesOfCodeNotCommented,

   Debt = nbLinesOfCodeNotCommented .Linear(20, 2,  200, 20).ToMinutes().ToDebt(),

   // The annual interest varies linearly from interest for severity major for 300 loc
   // to interest for severity critical for 2000 loc
   AnnualInterest = m.PercentageComment.Linear(
                         0,  8 *(Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes), 
                         20,     Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()  
}

//<Description>
// This rule matches methods with less than 10% of comment lines and that have 
// at least 20 lines of code. Such method might need to be more commented.
//
// See the definitions of the *Comments metric* here:
// http://www.ndepend.com/docs/code-metrics#PercentageComment
// http://www.ndepend.com/docs/code-metrics#NbLinesOfComment
// 
// Notice that only comments about the method implementation
// (comments in method body) are taken account.
//</Description>

//<HowToFix>
// Typically add more comment. But code commenting is subject to controversy.
// While poorly written and designed code would needs a lot of comment 
// to be understood, clean code doesn't need that much comment, especially
// if variables and methods are properly named and convey enough information.
// Unit-Test code can also play the role of code commenting.
//
// However, even when writing clean and well-tested code, one will have
// to write **hacks** at a point, usually to circumvent some API limitations or bugs.
// A hack is a non-trivial piece of code, that doesn't make sense at first glance,
// and that took time and web research to be found.
// In such situation comments must absolutely be used to express the intention, 
// the need for the hacks and the source where the solution has been found.
//
// The estimated Debt, which means the effort to comment such method,
// varies linearly from 2 minutes for 10 lines of code not commented,
// up to 20 minutes for 200 or more, lines of code not commented.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid types with poor cohesion</Name>
warnif count > 0 from t in JustMyCode.Types where 
  t.LCOM > 0.8  && 
  t.NbFields > 10 && 
  t.NbMethods >10 

  let poorCohesionScore = 1/(1.01 - t.LCOM)
  orderby poorCohesionScore descending

  select new { 
   t, 
   t.LCOM, 
   t.NbMethods, 
   t.NbFields,
   poorCohesionScore,

   Debt = poorCohesionScore.Linear(5, 5, 50, 4*60).ToMinutes().ToDebt(),

   // The annual interest varies linearly from interest for severity Medium for low poorCohesionScore
   // to 4 times interest for severity High for high poorCohesionScore
   AnnualInterest = poorCohesionScore.Linear(5,     Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
                                             50, 4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
   
}

//<Description>
// This rule is based on the *LCOM code metric*,
// LCOM stands for **Lack Of Cohesion of Methods**.
// See the definition of the LCOM metric here 
// http://www.ndepend.com/docs/code-metrics#LCOM
//
// The LCOM metric measures the fact that most methods are using most fields.
// A class is considered utterly cohesive (which is good)
// if all its methods use all its instance fields.
//
// Only types with enough methods and fields are taken account to avoid bias.
// The LCOM takes its values in the range [0-1].
//
// This rule matches types with LCOM higher than 0.8.
// Such value generally pinpoints a **poorly cohesive class**.
//</Description>

//<HowToFix>
// To refactor a poorly cohesive type and increase code quality and maintainability,
// certainly you'll have to split the type into several smaller and more cohesive types
// that together, implement the same logic.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 5 minutes for a type with a low poorCohesionScore,
// up to 4 hours for a type with high poorCohesionScore.
//</HowToFix>]]></Query>
    </Group>
    <Group Name="Code Smells Regression" Active="True" ShownInReport="False">
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>From now, all types added should respect basic quality principles</Name>
warnif count > 0 from t in JustMyCode.Types where

// Only match types added since Baseline.
// Uncomment this line to match also refactored types since Baseline.
// (t.WasAdded() || t.CodeWasChanged()) &&
   t.WasAdded() &&

// Eliminate interfaces, enumerations or types only with constant fields
// by making sure we are matching type with code.
t.NbLinesOfCode > 10 &&

// Optimization: Fast discard of non-relevant types 
(t.Fields.Count() > 20 || t.Methods.Count() > 20)
      
// Count instance fields and non-constant static fields
let fields = t.Fields.Where(f => 
      !f.IsLiteral &&
      !(f.IsStatic && f.IsInitOnly))

// Don't match these methods
let methods = t.Methods.Where(
   m => !(m.IsConstructor || m.IsClassConstructor ||
          m.IsGeneratedByCompiler ||
          m.IsPropertyGetter || m.IsPropertySetter ||
          m.IsEventAdder || m.IsEventRemover))
  
where 

// Low Quality types     Metrics' definitions are available here:
//     http://www.ndepend.com/docs/code-metrics#MetricsOnTypes
(  // Types with too many methods
   fields.Count() > 20 ||

   methods.Count() > 20 ||
               
   // Complex Types that use more than 50 other types
   t.NbTypesUsed > 50
)
select new { 
   t, 
   t.NbLinesOfCode, 

   instanceMethods = methods.Where(m => !m.IsStatic), 
   staticMethods = methods.Where(m => m.IsStatic),
  
   instanceFields = fields.Where(f => !f.IsStatic),
   staticFields = fields.Where(f => f.IsStatic),
  
   t.TypesUsed,

   // Constant Debt estimation, since for such type rules in category "Code Smells" 
   // accurately estimate the Debt.
   Debt     = 10.ToMinutes().ToDebt(),

   // The Severity is higher for new types than for refactored types 
   AnnualInterest= (t.WasAdded() ? 3 : 1) *
                    Severity.High.AnnualInterestThreshold()
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
// This rule operates only on types added since baseline.
//
// This rule can be easily modified to also match types refactored since baseline,
// that don't satisfy all quality criterions.
//
// Types matched by this rule not only have been recently added or refactored,
// but also somehow violate one or several basic quality principles,
// whether it has too many methods,
// it has too many fields,
// or is using too many types.
// Any of these criterions is often a symptom of a type with too many responsibilities.
//
// Notice that to count methods and fields, methods like constructors 
// or property and event accessors are not taken account.
// Notice that constants fields and static-readonly fields are not counted.
// Enumerations types are not counted also.
//</Description>

//<HowToFix>
// To refactor such type and increase code quality and maintainability,
// certainly you'll have to split the type into several smaller types
// that together, implement the same logic.
//
// Issues of this rule have a constant 10 minutes Debt, because the Debt,
// which means the effort to fix such issue, is already estimated for issues
// of rules in the category **Code Smells**.
//
// However issues of this rule have a **High** severity, with even more 
// interests for issues on new types since baseline, because the proper time 
// to increase the quality of these types is **now**, before they get commited 
// in the next production release.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>From now, all types added should be 100% covered by tests</Name>
warnif count > 0 from t in JustMyCode.Types where

// Only match types added since Baseline.
// Uncomment this line to match also refactored types since Baseline.
// (t.WasAdded() || t.CodeWasChanged()) &&
   t.WasAdded() &&

  // …that are not 100% covered by tests
  t.PercentageCoverage < 100

  let methodsCulprit = t.Methods.Where(m => m.PercentageCoverage < 100)

select new { 
   t, 
   t.PercentageCoverage, 
   methodsCulprit,
   t.NbLinesOfCode,

   // Constant Debt estimation, since for such type rules in category "Coverage" 
   // accurately estimate the untested code Debt.
   Debt     = 10.ToMinutes().ToDebt(),

   // The Severity is higher for new types than for refactored types 
   AnnualInterest= (t.WasAdded() ? 3 : 1) *
                    Severity.High.AnnualInterestThreshold()
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
// This rule operates only on types added since baseline.
//
// This rule can be easily modified to also match types refactored since baseline,
// that are not 100% covered by tests.
//
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// Often covering 10% of remaining uncovered code of a class, 
// requires as much work as covering the first 90%.
// For this reason, typically teams estimate that 90% coverage is enough.
// However *untestable code* usually means *poorly written code* 
// which usually leads to *error prone code*.
// So it might be worth refactoring and making sure to cover the 10% remaining code
// because **most tricky bugs might come from this small portion of hard-to-test code**.
//
// Not all classes should be 100% covered by tests (like UI code can be hard to test)
// but you should make sure that most of the logic of your application
// is defined in some *easy-to-test classes*, 100% covered by tests.
//
// In this context, this rule warns when a type added or refactored since the baseline,
// is not fully covered by tests.
//</Description>

//<HowToFix>
// Write more unit-tests dedicated to cover code not covered yet.
// If you find some *hard-to-test code*, it is certainly a sign that this code
// is not *well designed* and hence, needs refactoring.
//
// You'll find code impossible to cover by unit-tests, like calls to *MessageBox.Show()*.
// An infrastructure must be defined to be able to *mock* such code at test-time.
//
// Issues of this rule have a constant 10 minutes Debt, because the Debt,
// which means the effort to write tests for the culprit type, is already 
// estimated for issues in the category **Code Coverage**. 
//
// However issues of this rule have a **High** severity, with even more 
// interests for issues on new types since baseline, because the proper time 
// to write tests for these types is **now**, before they get commited 
// in the next production release.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>From now, all methods added should respect basic quality principles</Name>
warnif count > 0 from m in JustMyCode.Methods where

// Only match methods added since Baseline.
// Uncomment this line to match also refactored methods since Baseline.
// (m.WasAdded() || m.CodeWasChanged()) &&
   m.WasAdded() &&
 
// Low Quality methods// Metrics' definitions
(  m.NbLinesOfCode > 30 ||          // http://www.ndepend.com/docs/code-metrics#NbLinesOfCode
   m.NbILInstructions > 200 ||      // http://www.ndepend.com/docs/code-metrics#NbILInstructions
   m.CyclomaticComplexity > 20 ||   // http://www.ndepend.com/docs/code-metrics#CC
   m.ILCyclomaticComplexity > 50 || // http://www.ndepend.com/docs/code-metrics#ILCC
   m.ILNestingDepth > 4 ||          // http://www.ndepend.com/docs/code-metrics#ILNestingDepth
   m.NbParameters > 5 ||            // http://www.ndepend.com/docs/code-metrics#NbParameters
   m.NbVariables > 8 ||             // http://www.ndepend.com/docs/code-metrics#NbVariables
   m.NbOverloads > 6 )
select new { 
   m, 
   m.NbLinesOfCode,
   m.NbILInstructions,
   m.CyclomaticComplexity, 
   m.ILCyclomaticComplexity,
   m.ILNestingDepth, 
   m.NbParameters, 
   m.NbVariables, 
   m.NbOverloads, // http://www.ndepend.com/docs/code-metrics#NbOverloads

   // Constant Debt estimation, since for such method rules in category "Code Smells" 
   // accurately estimate the Debt.
   Debt     = 5.ToMinutes().ToDebt(),

   // The Severity is higher for new methods than for refactored methods
   AnnualInterest= (m.WasAdded() ? 3 : 1) *
                   Severity.High.AnnualInterestThreshold()
}  

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
// This rule operates only on methods added or refactored since the baseline.
//
// This rule can be easily modified to also match methods refactored since baseline,
// that don't satisfy all quality criterions.
//
// Methods matched by this rule not only have been recently added or refactored,
// but also somehow violate one or several basic quality principles,
// whether it is too large (too many *lines of code*), 
// too complex (too many *if*, *switch case*, loops…)
// has too many variables, too many parameters
// or has too many overloads.
//</Description>

//<HowToFix>
// To refactor such method and increase code quality and maintainability,
// certainly you'll have to split the method into several smaller methods
// or even create one or several classes to implement the logic.
//
// During this process it is important to question the scope of each
// variable local to the method. This can be an indication if
// such local variable will become an instance field of the newly created class(es).
//
// Large *switch…case* structures might be refactored through the help
// of a set of types that implement a common interface, the interface polymorphism
// playing the role of the *switch cases tests*.
//
// Unit Tests can help: write tests for each method before extracting it 
// to ensure you don't break functionality.
//
// Issues of this rule have a constant 5 minutes Debt, because the Debt,
// which means the effort to fix such issue, is already estimated for issues
// of rules in the category **Code Smells**.
// 
// However issues of this rule have a **High** severity, with even more 
// interests for issues on new methods since baseline, because the proper time 
// to increase the quality of these methods is **now**, before they get commited 
// in the next production release.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid decreasing code coverage by tests of types</Name>
warnif count > 0 
from t in JustMyCode.Types where
  t.IsPresentInBothBuilds() && t.CoverageDataAvailable && t.OlderVersion().CoverageDataAvailable
let locDiff = (int)t.NbLinesOfCode.Value - (int)t.OlderVersion().NbLinesOfCode.Value
where locDiff >= 0
let uncoveredLoc  = (int)t.NbLinesOfCodeNotCovered.Value - ((int)t.OlderVersion().NbLinesOfCodeNotCovered.Value + locDiff)
where uncoveredLoc > 0

orderby uncoveredLoc descending

select new { 
   t,
   OldCoveragePercent = t.OlderVersion().PercentageCoverage,
   NewCoveragePercent = t.PercentageCoverage,
   OldLoc = t.OlderVersion().NbLinesOfCode,
   NewLoc = t.NbLinesOfCode,
   uncoveredLoc,

   Debt = uncoveredLoc.Linear(1, 15,  100, 3*60).ToMinutes().ToDebt(),

   // The annual interest varies linearly from interest for severity High for one line of code that is not covered by tests anymore
   // to interest for severity Critical for 50 lines of code that are not covered by tests anymore
   AnnualInterest = uncoveredLoc.Linear(1,    Severity.High.AnnualInterestThreshold().Value.TotalMinutes, 
                                        50, 2*Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()
   

}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// This rule warns when the number of lines of a type covered by tests
// decreased since the baseline. In case the type faced some refactoring
// since the baseline, this loss in coverage is estimated only for types 
// with more lines of code, where # lines of code covered now is lower
// than # lines of code covered in baseline + the extra number of
// lines of code.
//
// Such situation can mean that some tests have been removed
// but more often, this means that the type has been modified,
// and that changes haven't been covered properly by tests.
//
// To visualize changes in code, right-click a matched type and select:
//
// • Compare older and newer versions of source file
//
// • or Compare older and newer versions disassembled with Reflector
//</Description>

//<HowToFix>
// Write more unit-tests dedicated to cover changes in matched types
// not covered yet.
// If you find some *hard-to-test code*, it is certainly a sign that this code
// is not *well designed* and hence, needs refactoring.
//
// The estimated Debt, which means the effort to cover by test 
// code that used to be covered, varies linearly 15 minutes to 3 hours,
// depending on the number of lines of code that are not covered by tests anymore.
//
// Severity of issues of this rule varies from **High** to **Critical** 
// depending on the number of lines of code that are not covered by tests anymore.
// Because the loss in code coverage happened since the baseline,
// the severity is high because it is important to focus on these issues 
// **now**, before such code gets released in production.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid making complex methods even more complex</Name>
warnif count > 0 

let complexityScoreProc = new Func<IMethod, double>(m => 
    (m.CyclomaticComplexity + m.ILCyclomaticComplexity/3 + 5*m.ILNestingDepth).Value)

from m in JustMyCode.Methods where
 !m.IsAbstract &&
  m.IsPresentInBothBuilds() &&
  m.CodeWasChanged() &&
  m.OlderVersion().CyclomaticComplexity > 6 

let complexityScore = complexityScoreProc(m)
let oldComplexityScore = complexityScoreProc(m.OlderVersion())
where complexityScore > oldComplexityScore 

let complexityScoreDiff = complexityScoreProc(m) - complexityScoreProc(m.OlderVersion())
orderby complexityScoreDiff descending

select new { 
   m,
   oldComplexityScore ,
   complexityScore ,
   diff= complexityScoreDiff,

   Debt = complexityScoreDiff.Linear(1, 15,   50, 60).ToMinutes().ToDebt(),

   // The annual interest varies linearly from interest for severity Medium for a tiny complexity increment
   // to interest for severity critical for 2000 loc
   AnnualInterest = complexityScoreDiff.Linear(1,     Severity.High.AnnualInterestThreshold().Value.TotalMinutes, 
                                               50, 4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
   
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// The method complexity is measured through the code metric
// *Cyclomatic Complexity* defined here:
// http://www.ndepend.com/docs/code-metrics#CC
//
// This rule warns when a method already complex
// (i.e with *Cyclomatic Complexity* higher than 6)
// become even more complex since the baseline.
//
// This rule needs assemblies PDB files and source code 
// to be available at analysis time, because the *Cyclomatic Complexity*
// is inferred from the source code and source code location
// is inferred from PDB files. See:
// http://www.ndepend.com/docs/ndepend-analysis-inputs-explanation
//
// To visualize changes in code, right-click a matched method and select:
//
// • Compare older and newer versions of source file
//
// • or Compare older and newer versions disassembled with Reflector
//</Description>

//<HowToFix>
// A large and complex method should be split in smaller methods, 
// or even one or several classes can be created for that.
//
// During this process it is important to question the scope of each
// variable local to the method. This can be an indication if
// such local variable will become an instance field of the newly created class(es).
//
// Large *switch…case* structures might be refactored through the help
// of a set of types that implement a common interface, the interface polymorphism
// playing the role of the *switch cases tests*.
//
// Unit Tests can help: write tests for each method before extracting it 
// to ensure you don't break functionality.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 15 to 60 minutes depending on the extra complexity added.
//
// Issues of this rule have a **High** severity, because it is important to focus 
// on these issues **now**, before such code gets released in production.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid making large methods even larger</Name>

warnif count > 0 
from m in JustMyCode.Methods where
 !m.IsAbstract &&

 // Eliminate constructors from match, since they get larger
 // as soons as some fields initialization are added.
 !m.IsConstructor &&
 !m.IsClassConstructor &&

  // Filter just here for optimization
  m.NbLinesOfCode > 15 &&

  m.IsPresentInBothBuilds() &&
  m.CodeWasChanged() 

let oldLoc = m.OlderVersion().NbLinesOfCode
where oldLoc > 15 && m.NbLinesOfCode > oldLoc

let diff = m.NbLinesOfCode - oldLoc
where diff > 0
orderby diff descending 

select new { 
   m,
   oldLoc,
   newLoc = m.NbLinesOfCode,
   diff,

   Debt = diff.Linear(1, 10,   100, 60).ToMinutes().ToDebt(),

   // The annual interest varies linearly from interest for severity Medium for a tiny complexity increment
   // to interest for severity critical for 2000 loc
   AnnualInterest = diff .Linear(1,      Severity.High.AnnualInterestThreshold().Value.TotalMinutes, 
                                 100, 4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
   
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule warns when a method already large
// (i.e with more than 15 lines of code)
// become even larger since the baseline.
//
// The method size is measured through the code metric
// *# Lines of Code* defined here:
// http://www.ndepend.com/docs/code-metrics#NbLinesOfCode
//
// This rule needs assemblies PDB files 
// to be available at analysis time, because the *# Lines of Code*
// is inferred from PDB files. See:
// http://www.ndepend.com/docs/ndepend-analysis-inputs-explanation
//
// To visualize changes in code, right-click a matched method and select:
//
// • Compare older and newer versions of source file
//
// • or Compare older and newer versions disassembled with Reflector
//</Description>

//<HowToFix>
// Usually too big methods should be split in smaller methods.
//
// But long methods with no branch conditions, that typically initialize some data,
// are not necessarily a problem to maintain, and might not need refactoring.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 5 to 20 minutes depending 
// on the number of lines of code added.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 10 to 60 minutes depending on the extra complexity added.
//
// Issues of this rule have a **High** severity, because it is important to focus 
// on these issues **now**, before such code gets released in production.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid adding methods to a type that already had many methods</Name>

warnif count > 0 

// Don't count constructors and methods generated by the compiler!
let getMethodsProc = new Func<IType, IList<IMethod>>(
   t => t.Methods.Where(m =>
      !m.IsConstructor && !m.IsClassConstructor && 
      !m.IsGeneratedByCompiler).ToArray()) 


from t in JustMyCode.Types where
  
  t.NbMethods > 30 &&   // Just here for optimization

  t.IsPresentInBothBuilds()

  // Optimization: fast discard of non-relevant types
  where t.OlderVersion().NbMethods > 30

  let oldMethods = getMethodsProc(t.OlderVersion())
  where oldMethods.Count > 30

  let newMethods = getMethodsProc(t)
  where newMethods.Count > oldMethods.Count

  let addedMethods = newMethods.Where(m => m.WasAdded())
  let removedMethods = oldMethods.Where(m => m.WasRemoved())

  orderby addedMethods.Count() descending

select new { 
   t,
   nbOldMethods = oldMethods.Count,
   nbNewMethods = newMethods.Count,
   addedMethods,
   removedMethods,

   Debt           = (10*addedMethods.Count()).ToMinutes().ToDebt(),
   AnnualInterest =     addedMethods.Count().Linear(
          1,       Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
          100,  4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// Types where number of methods is greater than 15 
// might be hard to understand and maintain.
//
// This rule lists types that already had more than 15 methods
// at the baseline time, and for which new methods have been added.
//
// Having many methods for a type might be a symptom
// of too many responsibilities implemented.
//
// Notice that constructors and methods generated by the compiler 
// are not taken account.
//</Description>

//<HowToFix>
// To refactor such type and increase code quality and maintainability,
// certainly you'll have to split the type into several smaller types
// that together, implement the same logic.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 10 minutes per method added.
//
// Issues of this rule have a **High** severity, because it is important to focus 
// on these issues **now**, before such code gets released in production.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid adding instance fields to a type that already had many instance fields</Name>

warnif count > 0 

let getFieldsProc = new Func<IType, IList<IField>>(
   t => t.Fields.Where(f => 
          !f.IsLiteral &&
          !f.IsGeneratedByCompiler &&
          !f.IsStatic).ToArray()) 


from t in JustMyCode.Types where
  
 !t.IsEnumeration &&
  t.IsPresentInBothBuilds()

  // Optimization: fast discard of non-relevant types
  where t.OlderVersion().NbFields > 15

  let oldFields = getFieldsProc(t.OlderVersion())
  where oldFields.Count > 15

  let newFields = getFieldsProc(t)
  where newFields.Count > oldFields.Count

  let addedFields = newFields.Where(f => f.WasAdded())
  let removedFields = oldFields.Where(f => f.WasRemoved())

  orderby addedFields.Count() descending

select new { 
   t,
   nbOldFields = oldFields.Count,
   nbNewFields = newFields.Count,
   addedFields,
   removedFields,

   Debt           = (10*addedFields.Count()).ToMinutes().ToDebt(),
   AnnualInterest =     addedFields.Count().Linear(
          1,       Severity.High.AnnualInterestThreshold().Value.TotalMinutes, 
          100,  4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()

}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// Types where number of fields is greater than 15 
// might be hard to understand and maintain.
//
// This rule lists types that already had more than 15 fields
// at the baseline time, and for which new fields have been added.
//
// Having many fields for a type might be a symptom
// of too many responsibilities implemented.
//
// Notice that *constants* fields and *static-readonly* fields are not taken account.
// Enumerations types are not taken account also.
//</Description>

//<HowToFix>
// To refactor such type and increase code quality and maintainability,
// certainly you'll have to group subsets of fields into smaller types
// and dispatch the logic implemented into the methods 
// into these smaller types.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 10 minutes per field added.
//
// Issues of this rule have a **High** severity, because it is important to focus 
// on these issues **now**, before such code gets released in production.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[//<Name>Avoid transforming an immutable type into a mutable one</Name>

warnif count > 0
from t in Application.Types where
   t.CodeWasChanged() &&
   t.OlderVersion().IsImmutable &&
  !t.IsImmutable && 
  // Don't take account of immutable types transformed into static types (not deemed as immutable)
  !t.IsStatic

let culpritFields = t.InstanceFields.Where(f => f.IsImmutable)
select new {
   t, 
   culpritFields,
   Debt = (10 + 10*culpritFields.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// A type is considered as *immutable* if its instance fields
// cannot be modified once an instance has been built by a constructor.
//
// Being immutable has several fortunate consequences for a type.
// For example its instance objects can be used concurrently 
// from several threads without the need to synchronize accesses.
//
// Hence users of such type often rely on the fact that the type is immutable.
// If an immutable type becomes mutable, there are chances that this will break 
// users code.
//
// This is why this rule warns about such immutable type that become mutable.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 2 minutes per instance field that became mutable.
//</Description>

//<HowToFix>
// If being immutable is an important property for a matched type,
// then the code must be refactored to preserve immutability.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 10 minutes plus 10 minutes per instance fields of
// the matched type that is now mutable.
//
// Issues of this rule have a **High** severity, because it is important to focus 
// on these issues **now**, before such code gets released in production.
//</HowToFix>]]></Query>
    </Group>
    <Group Name="Object Oriented Design" Active="True" ShownInReport="True">
      <Query Active="False" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid interfaces too big</Name>
warnif count > 0 

from i in JustMyCode.Types
where i.IsInterface && i.NbMethods >= 10 // Optimization  First threshold

// A get;set; property count as one method
let properties = i.Methods.Where(m => m.SimpleName.Length > 4 && (m.IsPropertyGetter || m.IsPropertySetter))
  .Distinct(m => m.SimpleName.Substring(4, m.SimpleName.Length -4))

// An event count as one method
let events = i.Methods.Where(m => (m.IsEventAdder|| m.IsEventRemover))
  .Distinct(m => m.SimpleName.Replace("add_","").Replace("remove_",""))

let methods = i.Methods.Where(m => !m.IsPropertyGetter && !m.IsPropertySetter && !m.IsEventAdder && !m.IsEventRemover)
let methodsCount = methods.Count() + properties.Count() + events.Count()
where methodsCount >= 10
let publicFactor = i.IsPubliclyVisible ? 1 : 0.5
orderby methodsCount descending
select new {  
   i, 
   Methods= methods,
   Properties = properties,
   Events = events,
   Debt = (publicFactor*methodsCount.Linear(10, 20,   100, 7*60)).ToMinutes().ToDebt(),
   // The annual interest varies linearly from interest for severity Medium for an interface with 10 methods
   // to interest for severity Critical for an interface with 100 methods and more
   AnnualInterest = (publicFactor*methodsCount.Linear(
                       10,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes,
                       100, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes))
                     .ToMinutes().ToAnnualInterest()
}


//<Description>
// This rule matches interfaces with more than 10 methods.
// Interfaces are abstractions and are meant to simplify the code structure.
// An interface should represent a single responsibility.
// Making an interface too large, too complex, necessarily means
// that the interface has too many responsibilities.
//
// A property with getter or setter or both count as one method.
// An event count as one method.
//</Description>

//<HowToFix>
// Typically to fix such issue, the interface must be refactored
// in a grape of smaller *single-responsibility* interfaces.
//
// A classic example is a *ISession* large interface, responsible
// for holding states, run commands and offer various accesses
// and facilities.
//
// The classic problem for a large public interface is that it has
// many clients that consume it. As a consequence splitting it in 
// smaller interfaces has an important impact and it is not always
// feasible.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from 20 minutes for an interface with 10 methods,
// up to 7 hours for an interface with 100 or more methods.
// The Debt is divided by two if the interface is not publicly
// visible, because in such situation only the current project is impacted
// by the refactoring.
//</HowToFix>
]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Base class should not use derivatives</Name>
warnif count > 0 
let excludedTypes = new[] {"TcpDiscoveryIpFinderBase", "EvictionPolicyBase", "PlatformTargetAdapter"}
from baseClass in JustMyCode.Types
where baseClass.IsClass  && !excludedTypes.Contains(baseClass.Name)
      && baseClass.NbChildren > 0 // <-- for optimization!
let derivedClassesUsed = baseClass.DerivedTypes.UsedBy(baseClass)
   // Don't warn when a base class is using nested private derived class
   .Where(derivedClass => 
            !(derivedClass.IsNested && 
              derivedClass.Visibility == Visibility.Private && 
              derivedClass.ParentType == baseClass
              ))
where derivedClassesUsed.Count() > 0

let derivedClassesMemberUsed = derivedClassesUsed.SelectMany(c => c.Members).UsedBy(baseClass)
orderby derivedClassesMemberUsed.Count() descending

select new { 
   baseClass, 
   derivedClassesUsed,
   derivedClassesMemberUsed,

   Debt = 3*(derivedClassesUsed.Count()+derivedClassesMemberUsed.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// In *Object-Oriented Programming*, the **open/closed principle** states:
// *software entities (components, classes, methods, etc.) should be open 
// for extension, but closed for modification*. 
// http://en.wikipedia.org/wiki/Open/closed_principle
//
// Hence a base class should be designed properly to make it easy to derive from,
// this is *extension*. But creating a new derived class, or modifying an
// existing one, shouldn't provoke any *modification* in the base class.
// And if a base class is using some derivative classes somehow, there
// are good chances that such *modification* will be needed.
//
// Extending the base class is not anymore a simple operation,
// this is not good design.
//
// Note that this rule doesn't warn when a base class is using a derived class 
// that is nested in the base class and declared as private. In such situation
// we consider that the derived class is an encapsulated implementation
// detail of the base class.
//</Description>

//<HowToFix>
// Understand the need for using derivatives, 
// then imagine a new design, and then refactor.
//
// Typically an algorithm in the base class needs to access something 
// from derived classes. You can try to encapsulate this access behind 
// an abstract or a virtual method.
//
// If you see in the base class some conditions on *typeof(DerivedClass)*
// not only *urgent refactoring* is needed. Such condition can easily 
// be replaced through an abstract or a virtual method.
//
// Sometime you'll see a base class that creates instance of some derived classes.
// In such situation, certainly using the *factory method pattern* 
// http://en.wikipedia.org/wiki/Factory_method_pattern
// or the *abstract factory pattern* 
// http://en.wikipedia.org/wiki/Abstract_factory_pattern
// will improve the design.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 3 minutes per derived class used by the base class +
// 3 minutes per member of a derived class used by the base class.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Class shouldn't be too deep in inheritance tree</Name>
        
warnif count > 0 from t in JustMyCode.Types 
where t.IsClass
let baseClasses = t.BaseClasses.ExceptThirdParty()
where baseClasses.Count() >= 3
orderby baseClasses.Count() descending

select new { 
   t, 
   baseClasses, 
   // The metric value DepthOfInheritance takes account
   // of third-party base classessee its definition here:
   // http://www.ndepend.com/docs/code-metrics#DIT
   t.DepthOfInheritance,
   Debt = (baseClasses.Count() -2)*3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Description>
// This rule warns about classes having 3 or more base classes.
// Notice that third-party base classes are not counted
// because this rule is about your code design, not 
// third-party libraries consumed design.
//
// *In theory*, there is nothing wrong having a *long inheritance chain*,
// if the modelization has been well thought out,
// if each base class is a well-designed refinement of the domain.
//
// *In practice*, modeling properly a domain demands a lot of effort
// and experience and more often than not, a *long inheritance chain*
// is a sign of confused design, that will be hard to work with and maintain.
//</Description>

//<HowToFix>
// In *Object-Oriented Programming*, a well-known motto is
// **Favor Composition over Inheritance**.
//
// This is because *inheritance* comes with pitfalls.
// In general, the implementation of a derived class is very bound up with 
// the base class implementation. Also a base class exposes implementation
// details to its derived classes, that's why it's often said that 
// inheritance breaks encapsulation. 
//
// On the other hands, *Composition* favors binding with interfaces
// over binding with implementations. Hence, not only the encapsulation
// is preserved, but the design is clearer, because interfaces make it explicit
// and less coupled.
//
// Hence, to break a *long inheritance chain*, *Composition* is often
// a powerful way to enhance the design of the refactored underlying logic.
//
// You can also read: 
// http://en.wikipedia.org/wiki/Composition_over_inheritance and
// http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance
//
// The estimated Debt, which means the effort to fix such issue,
// depends linearly upon the depth of inheritance.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Class with no descendant should be sealed if possible</Name>
warnif count > 0 from t in JustMyCode.Types where 
  t.IsClass && 
  t.NbChildren ==0 && 
 !t.IsSealed && 
 !t.IsStatic && 
 !t.IsPubliclyVisible // You might want to comment this condition 
                      // if you are developing an application,
                      // instead of developing a library
                      // with public classes that are intended to be 
                      // sub-classed by your clients.
  orderby t.NbLinesOfCode descending
select new {
   t,
   t.NbLinesOfCode,
   Debt = 30.ToSeconds().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// If a *non-static* class isn't declared with the keyword *sealed*,
// it means that it can be subclassed everywhere the *non-sealed* 
// class is visible.
//
// Making a class a *base class* requires significant design effort.
// Subclassing a *non-sealed* class, not initially designed 
// to be subclassed, will lead to unanticipated design issue.
//
// Most classes are *non-sealed* because developers don't care about 
// the keyword *sealed*, not because the primary intention was to write 
// a class that can be subclassed.
//
// There are minor performance gain in declaring a class as *sealed*.
// But the real benefit of doing so, is actually to **express the 
// intention**: *this class has not be designed to be a base class, 
// hence it is not allowed to subclass it*.
//
// Notice that by default this rule doesn't match *public* class
// to avoid matching classes that are intended to be sub-classed by
// third-party code using your library.
// If you are developing an application and not a library,
// just uncomment the clause *!t.IsPubliclyVisible*.
//</Description>

//<HowToFix>
// For each matched class, take the time to assess if it is really
// meant to be subclassed. Certainly most matched class will end up
// being declared as *sealed*.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Overrides of Method() should call base.Method()</Name>
warnif count > 0
from t in Types  // Take account of third-party base classes also

// Bother only classes with descendant
where t.IsClass && t.NbChildren > 0

from mBase in t.InstanceMethods
where  mBase.IsVirtual &&
      !mBase.IsThirdParty &&
      !mBase.IsAbstract && 
      !mBase.IsExplicitInterfaceImpl
from mOverride in mBase.OverridesDirectDerived
where !mOverride.IsUsing(mBase) &&
       JustMyCode.Contains(mOverride)  // Don't warn on generated code
select new { 
   mOverride, 
   shouldCall = mBase, 
   definedInBaseClass = mBase.ParentType,

   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Typically overrides of a base method, should **refine** or **complete** 
// the behavior of the base method. If the base method is not called, 
// the base behavior is not refined but it is *replaced*. 
//
// Violations of this rule are a sign of *design flaw*,
// especially if the actual design provides valid reasons 
// that advocates that the base behavior must be replaced and not refined.
//</Description>

//<HowToFix>
// You should investigate if *inheritance* is the right choice
// to bind the base class implementation with the derived classes
// implementations. Does presenting the method with polymorphic 
// behavior through an interface, would be a better design choice?
//
// In such situation, often using the design pattern **template method**
// http://en.wikipedia.org/wiki/Template_method_pattern might help
// improving the design.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Do not hide base class methods</Name>
warnif count > 0

// Define a lookup table indexing methods by their name including parameters signature.
let lookup = Methods.Where(m => !m.IsConstructor && !m.IsStatic && !m.IsGeneratedByCompiler)
                    .ToLookup(m1 => m1.Name)

from t in Application.Types
where !t.IsStatic && t.IsClass &&
   // Discard classes deriving directly from System.Object
   t.DepthOfInheritance > 1 
where t.BaseClasses.Any()

// For each methods not overriding any methods (new slot), 
// let's check if it hides by name some methods defined in base classes.
from m in t.InstanceMethods
where m.IsNewSlot && !m.IsExplicitInterfaceImpl && !m.IsGeneratedByCompiler

// Notice how lookup is used to quickly retrieve methods with same name as m.
// This makes the query 10 times faster than iterating each base methods to check their name.
let baseMethodsHidden = lookup[m.Name].Where(m1 => m1 != m && t.DeriveFrom(m1.ParentType))

where baseMethodsHidden.Count() > 0
select new { 
   m, 
   baseMethodsHidden,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// Method hiding is when a base class has a non-virtual method *M()*,
// and a derived class has also a method *M()* with the same signature.
// In such situation, calling *base.M()* does something different
// than calling *derived.M()*.
//
// Notice that this is not *polymorphic* behavior. With *polymorphic* 
// behavior, calling both *base.M()* and *derived.M()* on an instance 
// object of *derived*, invoke the same implementation.
//
// This situation should be avoided because it obviously leads to confusion.
// This rule warns about all method hiding cases in the code base.
//</Description>

//<HowToFix>
// To fix a violation of this rule, remove or rename the method, 
// or change the parameter signature so that the method does 
// not hide the base method.
//
// However *method hiding is for those times when you need to have two 
// things to have the same name but different behavior*. This is a very
// rare situations, described here:
// http://blogs.msdn.com/b/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>A stateless class or structure might be turned into a static type</Name>

warnif count > 0 from t in JustMyCode.Types where
  !t.IsStatic &&                  
  !t.IsGeneric &&
   t.InstanceFields.Count() == 0 &&

   // Don't match:
   // --> types that implement some interfaces.
   t.NbInterfacesImplemented == 0 &&

   // --> or classes that have sub-classes children.                            
   t.NbChildren == 0 &&

   // --> or classes that have a base class
   ((t.IsClass && t.DepthOfDeriveFrom("System.Object".AllowNoMatch()) == 1) ||
     t.IsStructure) 
   
let methodsUsingMe = t.TypesUsingMe.ChildMethods().Where(m => m.IsUsing(t))

select new {
   t,
   methodsUsingMe,
   Debt = (1 + methodsUsingMe.Count()).ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// This rule matches classes and structures that are not static, nor generic,
// that doesn't have any instance fields, that doesn't implement any interface
// nor has a base class (different than *System.Object*).
//
// Such class or structure is a *stateless* collection of *pure* functions, 
// that doesn't act on any *this* object data. Such collection of *pure* functions  
// is better hosted in a **static class**. Doing so simplifies the client code  
// that doesn't have to create an object anymore to invoke the *pure* functions.
//</Description>

//<HowToFix>
// Declare all methods as *static* and transform the class or structure
// into a *static* class.
// 
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Non-static classes should be instantiated or turned to static</Name>
warnif count > 0
from t in JustMyCode.Types
where  t.IsClass &&
    //!t.IsPublic &&   // if you are developing a framework, 
                       // you might not want to match public classes
      !t.IsStatic && 
      !t.IsAttributeClass && // Attributes class are never seen as instantiated

       // Don't suggest to turn to static, classes that implement interfaces
       t.InterfacesImplemented.Count() == 0 &&

      !t.DeriveFrom("System.MarshalByRefObject".AllowNoMatch()) && // Types instantiated through remoting infrastructure
        
      // XML serialized type might never be seen as instantiated.
      !t.HasAttribute("System.Xml.Serialization.XmlRootAttribute".AllowNoMatch()) &&
      !t.IsUsing("System.Xml.Serialization.XmlElementAttribute".AllowNoMatch()) &&
      !t.IsUsing("System.Xml.Serialization.XmlAttributeAttribute".AllowNoMatch()) &&
      
      // Serialized type might never be seen as instantiated.
      !t.HasAttribute("System.Runtime.Serialization.DataContractAttribute".AllowNoMatch()) &&
      !t.IsUsing("System.Runtime.Serialization.DataMemberAttribute".AllowNoMatch())
 
// find the first constructor of t called
let ctorCalled = t.Constructors.FirstOrDefault(ctor => ctor.NbMethodsCallingMe > 0)

// match t if none of its constructors is called.
where ctorCalled == null
select new { 
   t, 
   t.Visibility,
   Debt = 2.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

// Notice that classes only instantiated through reflection, like plug-in root classes
// are matched by this rules.

//<Description>
// If the constructors of a class are never called, the class is
// never instantiated, and should be defined as a *static class*.
//
// However this rule doesn't match instantiation through reflection.
// As a consequence, plug-in root classes, instantiated through reflection
// via *IoC frameworks*, can be *false positives* for this rule.
//
// Notice that by default this rule matches also *public* class.
// If you are developing a framework with classes that are intended 
// to be instantiated by your clients, just uncomment the line
// *!t.IsPublic*.
//</Description>

//<HowToFix>
// First it is important to investigate why the class is never instantiated.
// If the reason is *the class hosts only static methods* then the class
// can be safely declared as *static*.
//
// Others reasons like, *the class is meant to be instantiated via reflection*,
// or *is meant to be instantiated only by client code* should lead to
// adapt this rule code to avoid these matches.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods should be declared static if possible</Name>
warnif count > 0

from t in JustMyCode.Types.Where(t =>
   !t.IsStatic && !t.IsInterface &&
   !t.IsEnumeration && !t.IsDelegate &&
   !t.IsGeneratedByCompiler &&
   !t.FullName.Contains(".Jni."))

let methodsThatCanBeMadeStatic = 
   from m in t.InstanceMethods

   // An instance method can be turned to static if it is not virtual, 
   // not using the this reference and also, not using
   // any of its class or base classes instance fields or instance methods.
   where !m.IsAbstract && !m.IsVirtual &&
         !m.AccessThis && !m.IsExplicitInterfaceImpl &&
         m.Name != "get_IsLateAffinityAssignment()" &&
         m.Name != "set_IsLateAffinityAssignment(Boolean)" &&


          // Optimization: Using FirstOrDefault() avoid to check all members, 
          //               as soon as one member is found
          //               we know the method m cannot be made static.
          m.MembersUsed.FirstOrDefault(
              mUsed => !mUsed.IsStatic && 
                       (mUsed.ParentType == t || 
                        t.DeriveFrom(mUsed.ParentType))
          ) == null 
   select m

from m in methodsThatCanBeMadeStatic
let staticFieldsUsed = m.ParentType.StaticFields.UsedBy(m).Where(f => !f.IsGeneratedByCompiler)
let methodsCallingMe = m.MethodsCallingMe

select new { 
   m, 
   staticFieldsUsed,
   methodsCallingMe,
   Debt = (1 + methodsCallingMe.Count())*30.ToSeconds().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// When an instance method can be *safely* declared as static you should declare it as static.
//
// Whenever you write a method, you fulfill a contract in a given scope. 
// The narrower the scope is, the smaller the chance is that you write a bug.
//
// When a method is static, you can't access non-static members; hence, your scope is
// narrower. So, if you don't need and will never need (even in subclasses) instance
// fields to fulfill your contract, why give access to these fields to your method? 
// Declaring the method static in this case will let the compiler check that you 
// don't use members that you do not intend to use.
//
// Declaring a method as static if possible is also good practice because clients can 
// tell from the method signature that calling the method can't alter the object's state.
//
// Doing so, is also a micro performance optimization, since a static method is a 
// bit cheaper to invoke than an instance method, because the *this* reference* 
// doesn't need anymore to be passed.
//
// Notice that if a matched method is a handler, bound to an event through code  
// generated by a designer, declaring it as static might break the designer 
// generated code, if the generated code use the *this* invocation syntax, 
// (like *this.Method()*).
//</Description>

//<HowToFix>
// Declare matched methods as static.
//
// Since such method doesn't use any instance fields and methods of its type and 
// base-types, you should consider if it makes sense, to move such a method  
// to a static utility class.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Constructor should not call a virtual method</Name>
warnif count > 0

from t in Application.Types where 
   t.IsClass &&
  !t.IsGeneratedByCompiler &&
  !t.IsSealed

from ctor in t.Constructors 
let virtualMethodsCalled = 
   from mCalled in ctor.MethodsCalled
   where mCalled.IsVirtual && !mCalled.IsFinal && 
         // Only take care of just-my-code virtual methods called
         JustMyCode.Contains(mCalled) &&
         (  mCalled.ParentType == t ||
           (t.DeriveFrom(mCalled.ParentType) && 
            // Don't accept Object methods since they can be called
            // from another reference than the 'this' reference.
            mCalled.ParentType.FullName != "System.Object")
         )
   select mCalled
where virtualMethodsCalled.Count() > 0

select new { 
   ctor , 
   virtualMethodsCalled, 
   // If there is no derived type, it might be 
   // an opportunity to mark t as sealed.
   t.DerivedTypes,
   Debt = ((virtualMethodsCalled.Count())*6).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule matches constructors of a non-sealed class that call one or
// several virtual methods.
//
// When an object written in C# is constructed, what happens is that constructors 
// run in order from the base class to the most derived class.
//
// Also objects do not change type as they are constructed, but start out as 
// the most derived type, with the method table being for the most derived type. 
// This means that virtual method calls always run on the most derived type,
// even when calls are made from the constructor.
//
// When you combine these two facts you are left with the problem that if you 
// make a virtual method call in a constructor, and it is not the most derived 
// type in its inheritance hierarchy, then it will be called on a class whose 
// constructor has not been run, and therefore may not be in a suitable state 
// to have that method called.
//
// Hence this situation makes the class *fragile to derive from*.
//</Description>

//<HowToFix>
// Violations reported can be solved by re-designing object initialisation
// or by declaring the parent class as *sealed*, if possible.
//</HowToFix>
]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[//<Name>Avoid the Singleton pattern</Name>
warnif count > 0
from t in Application.Types
where !t.IsStatic && !t.IsAbstract && (t.IsClass || t.IsStructure) && t.Name != "Jvm" && t.Name != "JvmDll"

// All ctors of a singleton are private
where t.Constructors.Where(ctor => !ctor.IsPrivate).Count() == 0

// A singleton contains one static field of its parent type, to reference the unique instance
let staticFieldInstances = t.StaticFields.WithFieldType(t)
where staticFieldInstances.Count() == 1

let staticFieldInstance = staticFieldInstances.Single()
let methodsUsingField = staticFieldInstance.MethodsUsingMe
let methodsUsingField2 = methodsUsingField.Concat(methodsUsingField.SelectMany(m => m.MethodsCallingMe))

select new { 
   t, 
   staticFieldInstance,
   methodsUsingField2,
   Debt = (3*methodsUsingField2.Count()).ToMinutes().ToDebt(),
   AnnualInterest = (10+methodsUsingField2.Count()).ToMinutes().ToAnnualInterest()
}

//<Description>
// The *singleton pattern* consists in enforcing that a class has just
// a single instance: http://en.wikipedia.org/wiki/Singleton_pattern
// At first glance, this pattern looks appealing, it is simple to implement,
// it adresses a common situation, and as a consequence it is widely used.
//
// However, we discourage you from using singleton classes because experience
// shows that **singleton often results in less testable and less maintainable code**.
// Singleton is *by-design*, not testable. Each unit test should use their own objects
// while singleton forces multiple unit-tests to use the same instance object.
//
// Also the singleton static *GetInstance()* method allows *magic* access to that 
// single object and its state from wherever developers want! This potentially
// attractive facility unfortunatly ends up into *unorganized*/*messy* code that 
// will require effort to be refactored. 
// 
// More details available in these discussions:
//  http://codebetter.com/patricksmacchia/2011/05/04/back-to-basics-usage-of-static-members/
//  http://adamschepis.com/blog/2011/05/02/im-adam-and-im-a-recovering-singleton-addict/
//</Description>

//<HowToFix>
// This rule matches *the classic syntax of singletons*, where one   
// static field hold the single instance of the parent class. We underline that  
// *the problem is this particular syntax*, that plays against testability.
// The problem is not the fact that a single instance of the class lives 
// at runtime.
//
// Hence to fix matches fo this rule, creates the single instance 
// at the startup of the program, and pass it to all classes and methods
// that need to access it.
//
// If multiple singletons are identified, they actually form together a 
// *program execution context*. Such context can be unified in a unique
// singleton context. Doing so will make it easier to propagate the 
// context across the various program units.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 3 minutes per method relying on the singleton. 
// It is not rare that hundreds of methods rely on the singleton
// and that it takes hours to get rid of a singleton, refactoring
// the way just explained above.
//
// The severity of each singleton issue is **Critical** because as
// explained, using a the singleton pattern can really prevent the 
// whole program to be testable.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Don't assign static fields from instance methods</Name>
        
warnif count > 0
from f in Application.Fields where 
  f.IsStatic &&
 !f.IsLiteral &&
 !f.IsInitOnly &&
 !f.IsGeneratedByCompiler &&
  // Contract API define such a insideContractEvaluation static field
  f.Name != "insideContractEvaluation" &&
 !f.HasAttribute("System.ThreadStaticAttribute")
let assignedBy = f.MethodsAssigningMe.Where(m => !m.IsStatic)
where assignedBy .Count() > 0
select new { 
   f, 
   assignedBy,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}
     
//<Description>
// Assigning static fields from instance methods leads to
// poorly maintainable and non-thread-safe code.
//
// More discussion on the topic can be found here:
// http://codebetter.com/patricksmacchia/2011/05/04/back-to-basics-usage-of-static-members/
//</Description>

//<HowToFix>
// If the *static* field is just assigned once in the program
// lifetime, make sure to declare it as *readonly* and assign 
// it inline, or from the static constructor.
//
// In *Object-Oriented-Programming* the natural artifact 
// to hold states that can be modified is **instance fields**.
//
// Hence to fix violations of this rule, make sure to
// hold assignable states through *instance* fields, not
// through *static* fields.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid empty interfaces</Name>
warnif count > 0 from t in JustMyCode.Types where 
   t.IsInterface && 
   t.NbMethods == 0
select new { 
   t, 
   t.TypesThatImplementMe,
   Debt = (10 + 3*t.TypesThatImplementMe.Count()).ToMinutes().ToDebt(),
   Severity = t.TypesThatImplementMe.Any() ? Severity.Medium : Severity.Low
}

//<Description>
// Interfaces define members that provide 
// a behavior or usage contract. 
// The functionality that is described by the interface 
// can be adopted by any type, regardless of where the type 
// appears in the inheritance hierarchy. 
// A type implements an interface by providing implementations 
// for the members of the interface. 
// An empty interface does not define any members. 
// Therefore, it does not define a contract that can be implemented.
//
// If your design includes empty interfaces that types 
// are expected to implement, you are probably using an interface 
// as a marker or a way to identify a group of types. 
// If this identification will occur at run time, 
// the correct way to accomplish this is to use a custom attribute. 
// Use the presence or absence of the attribute, 
// or the properties of the attribute, to identify the target types. 
// If the identification must occur at compile time, 
// then it is acceptable to use an empty interface.
//</Description>

//<HowToFix>
// Remove the interface or add members to it. 
// If the empty interface is being used to label a set of types, 
// replace the interface with a custom attribute.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 10 minutes to discard an empty interface plus
// 3 minutes per type implementing an empty interface.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid types initialization cycles</Name>
warnif count > 0
 
// Types initialization cycle can only happen between types of an assembly.
from assembly in Application.Assemblies
                
let cctorSuspects = assembly.ChildMethods.Where(
  m => m.IsClassConstructor &&
       // Optimization: types involved in a type cycle necessarily don't have type level.
       m.ParentType.Level == null)

let excludedTypes = new [] 
{
    "Apache.Ignite.Core.Impl.Binary.BinaryObjectBuilder",
    "Apache.Ignite.Core.Impl.Binary.BinarySystemHandlers"
}.ToHashSet()

where cctorSuspects.Count() > 1
let typesSuspects = cctorSuspects.ParentTypes()
.Where(t => !excludedTypes.Contains(t.FullName))
.ToHashSet()

//
// dicoTmp associates to each type suspect T, a set of types from typesSuspects
// that contains at least a method or a field used directly or indirectly by the cctor of T.
//
let dicoTmp = cctorSuspects.ToDictionary(
    cctor => cctor.ParentType,
    cctor => ((IMember)cctor).ToEnumerable().FillIterative(
              members => from m in members 
                         from mUsed in (m is IMethod) ? (m as IMethod).MembersUsed : new IMember[0]
                         where mUsed.ParentAssembly == assembly 
                         select mUsed)
              .DefinitionDomain
              .Select(m => m.ParentType) // Don't need .Distinct() here, because of ToHashSet() below.
              .Except(cctor.ParentType)
              .Intersect(typesSuspects)
              .ToHashSet()
) 

//
// dico associates to each type suspect T, the set of types initialized (directly or indirectly)
// by the initialization of T. This second step is needed, because if a cctor of a type T1 
// calls a member of a type T2, not only the cctor of T1 triggers the initialization of T2,
// but also it triggers the initialization of all types that are initialized by T2 initialization.
//
let dico = typesSuspects.Where(t => dicoTmp[t].Count() > 0).ToDictionary(
   typeSuspect => typeSuspect,
   typeSuspect => typeSuspect.ToEnumerable().FillIterative(
                         types => from t in types
                                  from tUsed in dicoTmp[t]
                                  select tUsed)
                   .DefinitionDomain
                   .Except(typeSuspect)
                   .ToHashSet()
)


//
// Now that dico is prepared, detect the cctor cycles
//
from t in dico.Keys

   // Thanks to the work done to build dico, it is now pretty easy
   // to spot types involved in an initialization cyle with t! 
   let usersAndUseds = from tTmp in dico[t]
                       where dico.ContainsKey(tTmp) && dico[tTmp].Contains(t)
                       select tTmp
   where usersAndUseds.Count() > 0
 
   // Here we've found type(s) both using and used by the suspect type.
   // A cycle involving the type t is found!
   let typeInitCycle = usersAndUseds.Append(t)


   // Compute methodsCalled and fieldsUsed, useful to explore
   // how a cctor involved in a type initialization cycle, triggers other type initialization.
   let methodsCalledDepth = assembly.ChildMethods.DepthOfIsUsedBy(t.ClassConstructor)
   let fieldsUsedDepth = assembly.ChildFields.DepthOfIsUsedBy(t.ClassConstructor)

   let methodsCalled = methodsCalledDepth.DefinitionDomain.OrderBy(m => methodsCalledDepth[m]).ToArray()
   let fieldsUsed = fieldsUsedDepth.DefinitionDomain.OrderBy(f => fieldsUsedDepth[f]).ToArray()

// Use the tick box to: Group cctors methods By parent types
select new { 
   t.ClassConstructor, 
   cctorsCycle= typeInitCycle.Select(tTmp => tTmp.ClassConstructor),

   // methodsCalled and fieldsUsed are members used directly and indirectly by the cctor.
   // Export these members to the dependency graph (right click the cell Export/Append … to the Graph)
   // and see how the cctor trigger the initialization of other types
   methodsCalled,
   fieldsUsed,
   Debt = (20+10*typeInitCycle.Count()).ToMinutes().ToDebt(),
   Severity = Severity.Critical
}

//<Description>
// The *class constructor* (also called *static constructor*, and named *cctor* in IL code)
// of a type, if any, is executed by the CLR at runtime, the first time the type is used.
// A *cctor* doesn't need to be explicitly declared in C# or VB.NET, to exist in compiled IL code.
// Having a static field inline initialization is enough to have 
// the *cctor* implicitly declared in the parent class or structure.
//
// If the *cctor* of a type *t1* is using the type *t2* and if the *cctor* of *t2* is using *t1*,
// some type initialization unexpected and hard-to-diagnose buggy behavior can occur.
// Such a cyclic chain of initialization is not necessarily limited to two types
// and can embrace *N* types in the general case.
// More information on types initialization cycles can be found here:
// http://codeblog.jonskeet.uk/2012/04/07/type-initializer-circular-dependencies/
//
// The present code rule enumerates types initialization cycles.
// Some *false positives* can appear if some lambda expressions are defined 
// in *cctors* or in methods called by *cctors*. In such situation, this rule
// considers these lambda expressions as executed at type initialization time, 
// while it is not necessarily the case.
//</Description>

//<HowToFix>
// Types initialization cycles create confusion and unexpected behaviors.
// If several states hold by several classes must be initialized during the first
// access of any of those classes, a better design option is to create a dedicated 
// class whose responsibility is to initialize and hold all these states.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 20 minutes per cycle plus 10 minutes per type class constructor
// involved in the cycle.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Rules violated</Name>
from r in Rules
where r.IsViolated()
orderby r.Debt().Value descending
select new { 
   r, 
   Issues = r.Issues(), 
   Debt = r.Debt(), 
   AnnualInterest = r.AnnualInterest(), 
   BreakingPoint = r.BreakingPoint(),
   Category = r.Category
}

//<Description>
// **Debt**: Estimated effort to fix all rule issues.
//
// **Annual Interest**: Estimated annual cost to leave all rule issues unfixed.
//
// **Breaking Point**: Estimated point in time from now, when leaving the rule issues unfixed cost as much as fixing the rule issues.
// A low value indicates an a rule with easy-to-fix issue with high annual interest.
// This value can be used to prioritize issues fix, to significantly reduce interest with minimum effort.
//
// More documentation: http://www.ndepend.com/docs/technical-debt
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Critical issues (grouped per rules)</Name>
let issues = Issues.Where(i => i.Severity == Severity.Critical)
let rules = issues.ToLookup(i => i.Rule)
from grouping in rules
let r = grouping.Key
let ruleIssues = grouping.ToArray()
orderby ruleIssues.Length descending
let debt = ruleIssues.Sum(i => i.Debt)
let annualInterest = ruleIssues.Sum(i => i.AnnualInterest)
let breakingPoint = debt.BreakingPoint(annualInterest)
select new { r, 
             ruleIssues, 
             debt,
             annualInterest, 
             breakingPoint,
             Category = r.Category
}

//<Description>
// Issues with a Critical severity level shouldn't move to production. It still can for business imperative needs purposes, but at worth it must be fixed during the next iterations.
//
// **Debt**: Estimated effort to fix the rule issues.
//
// **Annual Interest**: Estimated annual cost to leave the rule issues unfixed.
//
// **Breaking Point**: Estimated point in time from now, when leaving the 
// rule issues unfixed cost as much as fixing the issues.
// A low value indicates easy-to-fix issues with high annual interest.
// This value can be used to prioritize issues fix, to significantly 
// reduce interest with minimum effort.
//
// **Unfold** the cell in *ruleIssues* column to preview all its issues.
//
// **Double-click a rule** to edit the rule and list all its issues.
//
// More documentation: http://www.ndepend.com/docs/technical-debt
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Rules violated</Name>
from r in Rules
where r.IsViolated()
orderby r.Debt().Value descending
select new { 
   r, 
   Issues = r.Issues(), 
   Debt = r.Debt(), 
   AnnualInterest = r.AnnualInterest(), 
   BreakingPoint = r.BreakingPoint(),
   Category = r.Category
}

//<Description>
// **Debt**: Estimated effort to fix all rule issues.
//
// **Annual Interest**: Estimated annual cost to leave all rule issues unfixed.
//
// **Breaking Point**: Estimated point in time from now, when leaving the rule issues unfixed cost as much as fixing the rule issues.
// A low value indicates an a rule with easy-to-fix issue with high annual interest.
// This value can be used to prioritize issues fix, to significantly reduce interest with minimum effort.
//
// More documentation: http://www.ndepend.com/docs/technical-debt
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Quality Gates Evolution</Name>
from qg in QualityGates
let qgBaseline = qg.OlderVersion()
let relyOnDiff = qgBaseline == null
let evolution = relyOnDiff ? (TrendIcon?)null : 
                // When a quality gate relies on diff between now and baseline
                // it is not executed against the baseline
                qg.ValueDiff() == 0d ?
                TrendIcon.Constant :
                (qg.ValueDiff() > 0 ? 
                  ( qg.MoreIsBad ?  TrendIcon.RedUp: TrendIcon.GreenUp) :
                  (!qg.MoreIsBad ?  TrendIcon.RedDown: TrendIcon.GreenDown))
select new { qg, 
   Evolution      =  evolution,

   BaselineStatus =  relyOnDiff? (QualityGateStatus?) null : qgBaseline.Status,
   Status         =  qg.Status,

   BaselineValue  =  relyOnDiff? (null) : qgBaseline.ValueString,
   Value          =  qg.ValueString, 
}
 
// <Description>
// Show quality gates evolution between baseline and now.
//
// When a quality gate relies on diff between now and baseline (like *New Debt since Baseline*)
// it is not executed against the baseline and as a consequence its evolution is not available.
//
// Double-click a quality gate for editing.
// </Description>]]></Query>
    </Group>
    <Group Name="Design" Active="True" ShownInReport="False">
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid custom delegates</Name>
warnif count > 0 
from t in JustMyCode.Types where t.IsDelegate

let invokeMethod = (from m in t.Methods where m.SimpleName == "Invoke" select m).Single()
let signature1 = invokeMethod.Name.Substring(
   invokeMethod.SimpleName.Length, 
   invokeMethod.Name.Length - invokeMethod.SimpleName.Length)

// 'ref' and 'out' parameters cannot be supported
where !signature1.Contains("&")

let signature2 = signature1.Replace("(","<").Replace(")",">")
let signature3 = signature2 == "<>" ? "" : signature2
let resultTypeName = invokeMethod.ReturnType == null ? "????" :
                     invokeMethod.ReturnType.FullName == "System.Void" ? "" :
                     invokeMethod.ReturnType.Name
let replaceWith = 
      resultTypeName == "Boolean" && invokeMethod.NbParameters == 1 ?
   "Predicate" + signature3 : resultTypeName == "" ?
   "Action" + signature3  : invokeMethod.NbParameters ==0 ?
   "Func<" + resultTypeName + ">" :
   "Func" + signature3.Replace(">", "," + resultTypeName + ">")
   
let methodsUser = t.TypesUsingMe.ChildMethods().Where(m => m.IsUsing(t))
          
select new { 
   t, 
   replaceWith,
   methodsUser,
   Debt = (5 + 3*methodsUser.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// Generic delegates sould be preferred over custom delegates.
// Generic delegates are:
//
// • *Action<…>* to represent any method with *void* return type.
//
// • *Func<…>* to represent any method with a return type. The last 
// generic argument is the return type of the prototyped methods.
//
// • *Predicate<T>* to represent any method that takes an instance
// of *T* and that returns a *boolean*.
//
// • Expression<…> that represents function definitions that can be 
// compiled and subsequently invoked at runtime but can also be 
// serialized and passed to remote processes.
//
// Thanks to generic delegates, not only the code using these custom 
// delegates will become clearer, but you'll be relieved from the 
// maintenance of these delegate types.
//
// Notice that delegates that are consumed by *DllImport* extern methods
// must not be converted, else this could provoke marshalling issues.
//</Description>

//<HowToFix>
// Remove custom delegates and replace them with generic
// delegates shown in the **replaceWith** column.
//
// The estimated Debt, which means the effort to fix such issue,
// is 5 minutes per custom delegates plus 3 minutes per method
// using such custom delegate.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types with disposable instance fields must be disposable</Name>
        
warnif count > 0

// Several IDisposable types can be found if several .NET Fx are referenced.
let iDisposables = ThirdParty.Types.WithFullName("System.IDisposable")
where iDisposables.Any() // in case the code base doesn't use at all System.IDisposable

from t in Application.Types.Except(Application.Types.ThatImplementAny(iDisposables))
where !t.IsGeneratedByCompiler 

let instanceFieldsDisposable = 
    t.InstanceFields.Where(f => f.FieldType != null &&
                                f.FieldType.InterfacesImplemented.Intersect(iDisposables).Any())

where instanceFieldsDisposable.Any()
select new { 
   t, 
   instanceFieldsDisposable,
   Debt = (5 + 2*instanceFieldsDisposable.Count()).ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule warns when a class declares and implements an instance field that 
// is a *System.IDisposable* type and the class does not implement *IDisposable*.
//
// A class implements the *IDisposable* interface to dispose of unmanaged resources 
// that it owns. An instance field that is an *IDisposable* type indicates that 
// the field owns an unmanaged resource. A class that declares an *IDisposable* 
// field indirectly owns an unmanaged resource and should implement the 
// *IDisposable* interface. If the class does not directly own any unmanaged 
// resources, it should not implement a finalizer.
//
// This rules might report false positive in case the lifetime of the disposable 
// objects referenced, is longer than the lifetime of the object that hold the 
// disposable references.
//</Description>

//<HowToFix>
// To fix a violation of this rule, implement *IDisposable* and from the 
// *IDisposable.Dispose()* method call the *Dispose()* method of the field(s).
//
// The estimated Debt, which means the effort to fix such issue,
// is 5 minutes per type matched plus 3 minutes per disposable instance field.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Disposable types with unmanaged resources should declare finalizer</Name>

// This default rule is disabled by default,
// see in the rule description (below) why.
// warnif count > 0

// Several IDisposable type can be found if several .NET Fx are referenced.
let iDisposables = ThirdParty.Types.WithFullName("System.IDisposable")
where iDisposables.Any() // in case the code base doesn't use at all System.IDisposable

let disposableTypes = Application.Types.ThatImplementAny(iDisposables)
let unmanagedResourcesFields = disposableTypes.ChildFields().Where(f => 
   !f.IsStatic && 
    f.FieldType != null && 
    f.FieldType.FullName.EqualsAny(
       "System.IntPtr",
       "System.UIntPtr",
       "System.Runtime.InteropServices.HandleRef")).ToHashSet()
let disposableTypesWithUnmanagedResource = unmanagedResourcesFields.ParentTypes()

from t in disposableTypesWithUnmanagedResource
where !t.HasFinalizer
let unmanagedResourcesTypeFields = unmanagedResourcesFields.Intersect(t.InstanceFields)
select new { 
   t, 
   unmanagedResourcesTypeFields,
   //Debt = 10.ToMinutes().ToDebt(),
   //Severity = Severity.Critical
}

//<Description>
//A type that implements *System.IDisposable*, 
//and has fields that suggest the use of unmanaged resources, 
//does not implement a finalizer as described by *Object.Finalize()*.
//A violation of this rule is reported 
//if the disposable type contains fields of the following types:
//
// • *System.IntPtr*
//
// • *System.UIntPtr*
//
// • *System.Runtime.InteropServices.HandleRef*
//
// Notice that this default rule is disabled by default,
// because it typically reports *false positive* for classes
// that just hold some references to managed resources,
// without the responsibility to dispose them.
//
// To enable this rule just uncomment *warnif count > 0*.
//</Description>

//<HowToFix>
//To fix a violation of this rule, 
//implement a finalizer that calls your *Dispose()* method.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Methods that create disposable object(s) and that don't call Dispose()</Name>
 
// Uncomment this to transform this code query into a code rule.
// warnif count > 0

// Several IDisposable types can be found if several .NET Fx are referenced.
let iDisposables = ThirdParty.Types.WithFullName("System.IDisposable")
where iDisposables.Any() // in case the code base doesn't use at all System.IDisposable
 
// Build sequences of disposableTypes and disposeMethods
let disposableTypes = Types.ThatImplementAny(iDisposables).Concat(iDisposables)
let disposeMethods = disposableTypes.ChildMethods().WithName("Dispose()").ToHashSet()


// -> You can refine this code query by assigning to disposableTypesToLookAfter something like:
//    disposableTypes.WithFullNameIn("Namespace.TypeName1", "Namespace.TypeName2", ...)
let disposableTypesToLookAfter = disposableTypes


// -> You can refine this code query by assigning to methodsToLookAfter something like:
//    Application.Assemblies.WithNameLike("Asm").ChildMethods()
let methodsToLookAfter = Application.Methods


// Enumerate methods that create any disposable type, without calling Dispose()
from m in methodsToLookAfter.ThatCreateAny(disposableTypesToLookAfter )

where !m.MethodsCalled.Intersect(disposeMethods).Any()
select new {
   m,
   disposableObjectsCreated = disposableTypes.Where(t => m.CreateA(t)),
   m.MethodsCalled,
   //Debt = 10.ToMinutes().ToDebt(),
   //Severity = Severity.Low
}

//<Description>
// This code query enumerates methods that create one or several disposable object(s), 
// without calling any Dispose() method.
//
// This code query is not a code rule because it is acceptable to do so, 
// as long as disposable objects are disposed somewhere else.
//
// This code query is designed to be be easily refactored 
// to look after only specific disposable types, or specific caller methods. 
//
// You can then refactor this code query to adapt it to your needs and transform it into a code rule.
//</Description>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Classes that are candidate to be turned into structures</Name>

warnif count > 0 from t in JustMyCode.Types where 
  t.IsClass &&
 !t.IsGeneratedByCompiler &&
 !t.IsStatic &&
  t.SizeOfInst > 0 &&
  t.SizeOfInst <= 16 &&   // Structure instance must not be too big, 
                          // else it degrades performance.

  t.NbChildren == 0 &&    // Must not have children

  // Must not implement interfaces to avoid boxing mismatch 
  // when structures implements interfaces.
  t.InterfacesImplemented.Count() == 0 &&

  // Must derive directly from System.Object
  t.DepthOfDeriveFrom("System.Object".AllowNoMatch()) == 1 &&

  // Must not be a serializable class because a structure should be immutable
  // and serialized types are mutable.
  !t.HasAttribute("System.Xml.Serialization.XmlRootAttribute".AllowNoMatch()) &&
  !t.IsUsing("System.Xml.Serialization.XmlElementAttribute".AllowNoMatch()) &&
  !t.IsUsing("System.Xml.Serialization.XmlAttributeAttribute".AllowNoMatch()) &&    
  !t.HasAttribute("System.Runtime.Serialization.DataContractAttribute".AllowNoMatch()) &&
  !t.IsUsing("System.Runtime.Serialization.DataMemberAttribute".AllowNoMatch())

  // && t.IsSealed    <-- You might want to add this condition 
  //                      to restraint the set.
  // && t.IsImmutable <-- Structures should be immutable type.
  // && t.!IsPublic   <-- You might want to add this condition if 
  //                      you are developping a framework with classes 
  //                      that are intended to be sub-classed by 
  //                      your clients.
  let methodsUser = t.TypesUsingMe.ChildMethods().Where(m => m.IsUsing(t))

select new { 
   t, 
   t.SizeOfInst, 
   t.InstanceFields,
   methodsUser,
   Debt = (5 + 1*methodsUser.Count()).ToMinutes().ToDebt(),
   Severity = Severity.Low
} 

//<Description>
// *Int32*, *Double*, *Char* or *Boolean* are structures and not classes.
// Structures are particularly suited to implement **lightweight values**.
// Hence a class is candidate to be turned into a structure
// when its instances are *lightweight values*.
//
// This is a matter of *performance*. It is expected that a program
// works with plenty of *short lived lightweight values*.
// In such situation, the advantage of using *struct* instead of
// *class*, (in other words, the advantage of using *values* instead
// of *objects*), is that *values* are not managed by the garbage collector.
// This means that values are cheaper to deal with. 
//
// This rule matches classes that looks like being *lightweight values*.
// The characterization of such class is:
//
// • Its instances have a small *memory footprint* (at most 16 bytes)
//
// • Its instances have a memory footprint greater than zero
// (i.e the class has at least one instance field).
//
// • It implements no interfaces.
//
// • It has no derived classes.
//
// • It derives directly from *System.Object*.
//
// This rule doesn't take account if instances of matched
// classes are numerous *short-lived* objects.
// These criterions are just indications. Only you can decide if it is 
// *performance wise* to transform a class into a structure.
//
// A related case-study of using *class* or *struct* for *Tuple<…>* generic 
// types can be found here:
// http://stackoverflow.com/questions/2410710/why-is-the-new-tuple-type-in-net-4-0-a-reference-type-class-and-not-a-value-t
//</Description>

//<HowToFix>
// Just use the keyword *struct* instead of the keyword *class*.
//
// **CAUTION:** Before applying this rule, make sure to understand 
// the **deep implications** of transforming a class into a structure.
// http://msdn.microsoft.com/en-us/library/aa664471(v=vs.71).aspx
//
// The estimated Debt, which means the effort to fix such issue,
// is 5 minutes per class matched plus one minute per method
// using such class transformed into a structure.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid namespaces with few types</Name>
warnif count > 0 from n in JustMyCode.Namespaces 
where n.Name.Length > 0 // Don't match anonymous namespaces
let types = n.ChildTypes.Where(t => !t.IsGeneratedByCompiler)
where 
  types.Count() < 5 
  orderby types.Count() ascending
select new { 
   n, 
   types,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Low
} 

//<Description>
// This rule warns about namespaces other than the global namespace 
// that contain less than five types.
//
// Make sure that each of your namespaces has a logical organization
// and that a valid reason exists to put types in a sparsely 
// populated namespace. 
// 
// Namespaces should contain types that are used together in most 
// scenarios. When their applications are mutually exclusive, 
// types should be located in separate namespaces. For example, 
// the *System.Web.UI* namespace contains types that are used 
// in Web applications, and the *System.Windows.Forms* namespace 
// contains types that are used in Windows-based applications. 
// Even though both namespaces have types that control aspects 
// of the user interface, these types are not designed for 
// use in the same application. Therefore, they are located in 
// separate namespaces.
//
// Careful namespace organization can also be helpful because 
// it increases the discoverability of a feature. By examining the 
// namespace hierarchy, library consumers should be able to locate
// the types that implement a feature.
//</Description>

//<HowToFix>
// To fix a violation of this rule, try to combine namespaces 
// that contain just a few types into a single namespace.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Nested types should not be visible</Name>
warnif count > 0 from t in JustMyCode.Types where 
  t.IsNested && 
 !t.IsGeneratedByCompiler &&
 !t.IsPrivate 
let typesUser = t.TypesUsingMe.Where(t1 => t1 != t.ParentType && t1.ParentType != t.ParentType)
select new { 
   t, 
   t.Visibility,
   typesUser,
   Debt = (2 + 4*typesUser.Count()).ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Description>
// This rule warns about nested types not declared as private.
//
// A nested type is a type declared within the scope of another 
// type. Nested types are useful for encapsulating private 
// implementation details of the containing type. Used 
// for this purpose, nested types should not be externally visible.
//
// Do not use externally visible nested types for logical 
// grouping or to avoid name collisions; instead use namespaces.
//
// Nested types include the notion of member accessibility, 
// which some programmers do not understand clearly.
//
// Protected types can be used in subclasses and nested types 
// in advanced customization scenarios.
//</Description>

//<HowToFix>
// If you do not intend the nested type to be externally visible,
// change the type's accessibility. 
//
// Otherwise, remove the nested type from its parent and make it 
// *non-nested*.
//
// If the purpose of the nesting is to group some nested types, 
// use a namespace to create the hierarchy instead.
//
// The estimated Debt, which means the effort to fix such issue,
// is 2 minutes per nested type plus 4 minutes per outter type
// using such nesting type.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Declare types in namespaces</Name>
warnif count > 0 from n in Application.Namespaces where 
  // If an anonymous namespace can be found, 
  // it means that it contains types outside of namespaces.
  n.Name == ""

  // Eliminate anonymous namespaces that contains
  // only generated types. 
  let childTypes = n.ChildTypes.Where(t => !t.IsGeneratedByCompiler)
  where childTypes.Count() > 0
select new { 
   n, 
   childTypes,
   n.NbLinesOfCode,
   Debt = 2*childTypes.Count().ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Description>
// Types are declared within namespaces to prevent name collisions,
// and as a way of organizing related types in an object hierarchy.
//
// Types outside any named namespace are in a *global 
// namespace* that cannot be referenced in code.
//
// The *global namespace* has no name, hence it is qualified as
// being the *anonymous namespace*.
//
// This rule warns about *anonymous namespaces*.
//</Description>

//<HowToFix>
// To fix a violation of this rule, 
// declare all types of all anonymous 
// namespaces in some named namespaces.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Empty static constructor can be discarded</Name>
warnif count > 0 from m in Application.Methods where 
  m.IsClassConstructor && 
  m.NbLinesOfCode == 0
select new { 
   m,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// The *class constructor* (also called *static constructor*, and named *cctor* in IL code)
// of a type, if any, is executed by the CLR at runtime, just before the first time the type is used.
//
// This rule warns about the declarations of *static constructors*
// that don't contain any lines of code. Such *cctors* are useless
// and can be safely removed.
//</Description>

//<HowToFix>
// Remove matched empty *static constructors*.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Instances size shouldn't be too big</Name>
warnif count > 0 from t in JustMyCode.Types where 
  t.SizeOfInst > 64 
  orderby t.SizeOfInst descending
select new { 
   t, 
   t.SizeOfInst, 
   t.InstanceFields,
   Debt = t.SizeOfInst.Linear(64,2, 2048, 60).ToMinutes().ToDebt(),

   // The annual interest varies linearly from interests for severity Medium for 64 bytes per instance
   // to twice interests for severity High for 2048 bytes per instance
   AnnualInterest = t.SizeOfInst.Linear(64,      Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
                                        2048, 2*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
   
}

//<Description>
// Types where *SizeOfInst > 64* might degrade performance 
// if many instances are created at runtime. 
// They can also be hard to maintain. 
//
// Notice that a class with a large *SizeOfInst* value
// doesn't necessarily have a lot of instance fields.
// It might derive from a class with a large *SizeOfInst* value.
//
// See the definition of the *SizeOfInst* metric here 
// http://www.ndepend.com/docs/code-metrics#SizeOfInst
//</Description>

//<HowToFix>
// A type with a large *SizeOInst* value hold *directly* 
// a lot of data. Typically, you can group this data into 
// smaller types that can then be composed.
//
// The estimated Debt, which means the effort to fix such issue,
// varies linearly from interests for severity Medium for 64 bytes per instance
// to twice interests for severity High for 2048 bytes per instance.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Boxing/unboxing should be avoided</Name>
warnif percentage > 5 from m in JustMyCode.Methods where 
  m.IsUsingBoxing || 
  m.IsUsingUnboxing
select new { 
   m, 
   m.NbLinesOfCode, 
   m.IsUsingBoxing, 
   m.IsUsingUnboxing,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Low
} 

//<Description>
// *Boxing* is the process of converting a value type to the type 
// *object* or to any interface type implemented by this value 
// type. When the CLR boxes a value type, it wraps the value 
// inside a *System.Object* and stores it on the managed heap.
//
// *Unboxing* extracts the value type from the object. Boxing 
// is implicit; unboxing is explicit.
//
// The concept of boxing and unboxing underlies the C# unified 
// view of the type system in which a value of any type can 
// be treated as an object. More about *boxing* and *unboxing*
// here: https://msdn.microsoft.com/en-us/library/yz2be5wk.aspx
//
// This rule warns when more than 5% of methods in a code base
// are using *boxing* or *unboxing*. Because *boxing* and 
// *unboxing* come with a performance penalty and can be often 
// avoided.
//</Description>

//<HowToFix>
// Thanks to .NET generic, and especially thanks to 
// generic collections, *boxing* and *unboxing* should 
// be rarely used. Hence in most situations the code can 
// be refactored to avoid relying on *boxing* and *unboxing*.
// See for example:
// http://stackoverflow.com/questions/4403055/boxing-unboxing-and-generics
//
// With a performance profiler, indentify methods that consume 
// a lot of CPU time. If such method uses *boxing* or 
// *unboxing*, especially in a **loop**, make sure to refactor it.
//
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Attribute classes should be sealed</Name>
warnif count > 0 from t in Application.Types where 
  t.IsAttributeClass && 
 !t.IsSealed && 
 !t.IsAbstract && 
  t.IsPublic
select new {
   t, 
   t.NbLinesOfCode,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Description>
// The .NET Framework class library provides methods 
// for retrieving custom attributes. By default, 
// these methods search the attribute inheritance 
// hierarchy; for example 
// *System.Attribute.GetCustomAttribute()* 
// searches for the specified attribute type, or any 
// attribute type that extends the specified attribute 
// type.
//
// Sealing the attribute eliminates the search 
// through the inheritance hierarchy, and can improve 
// performance.
//</Description>

//<HowToFix>
// To fix a violation of this rule, seal the attribute 
// type or make it abstract.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Don't use obsolete types, methods or fields</Name>   
warnif count > 0
let obsoleteTypes =   Types.Where(t => t.IsObsolete)
let obsoleteMethods = Methods.Where(m => m.IsObsolete).ToHashSet()
let obsoleteFields =  Fields.Where(f => f.IsObsolete)

from m in JustMyCode.Methods.UsingAny(obsoleteTypes).Union(
          JustMyCode.Methods.UsingAny(obsoleteMethods)).Union(
          JustMyCode.Methods.UsingAny(obsoleteFields))
let obsoleteTypesUsed = obsoleteTypes.UsedBy(m)

// Optimization: MethodsCalled + Intersect() is faster than using obsoleteMethods.UsedBy()
let obsoleteMethodsUsed = m.MethodsCalled.Intersect(obsoleteMethods)
let obsoleteFieldsUsed = obsoleteFields.UsedBy(m)

let obsoleteUsage = obsoleteTypesUsed.Cast<IMember>().Concat(obsoleteMethodsUsed).Concat(obsoleteFieldsUsed)

select new {
   m, 
   obsoleteUsage,
   Debt = (5*obsoleteUsage.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// The attribute *System.ObsoleteAttribute* is used to tag
// types, methods or fields of an API that clients shouldn't 
// use because these code elements will be removed sooner
// or later.
//
// This rule warns about methods that use a type, a method
// or a field, tagged with *System.ObsoleteAttribute*.
//</Description>

//<HowToFix>
// Typically when a code element is tagged with
// *System.ObsoleteAttribute*, a *workaround message*
// is provided to clients.
//
// This *workaround message* will tell you what to do
// to avoid using the obsolete code element.
//
// The estimated Debt, which means the effort to fix such issue,
// is 5 minutes per type, method or field used.
//
// Issues of this rule have a severity **High**
// because it is important to not rely anymore on obsolete code.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Do implement methods that throw NotImplementedException</Name>
warnif count > 0
from m in Application.Methods
where m.CreateA("System.NotImplementedException".AllowNoMatch())
select new {
   m,
   m.NbLinesOfCode,
   Debt = (m.NbLinesOfCode == 1 ? 10 : 3).ToMinutes().ToDebt(),
   Severity = m.NbLinesOfCode == 1 ? Severity.High : Severity.Medium
}

//<Description>
// The exception *NotImplementedException* is used to declare 
// a method *stub* that can be invoked, and defer the  
// development of the method implementation.
//
// This exception is especially useful when doing **TDD**
// (*Test Driven Development*) when tests are written first.
// This way tests fail until the implementation is written.
//
// Hence using *NotImplementedException* is a *temporary*
// facility, and before releasing, will come a time when 
// this exception shouldn't be used anywhere in code.
//
// *NotImplementedException* should not be used permanently
// to mean something like *this method should be overriden*
// or *this implementation doesn't support this facility*.
// Artefact like *abstract method* or *abstract class* should 
// be used instead, to favor a *compile time* error over a 
// *run-time* error.
//
// This rule warns about method still using 
// *NotImplementedException*.
//</Description>

//<HowToFix>
// Investigate why *NotImplementedException* is still 
// thrown.
//
// Such issue has a **High** severity if the method code
// consists only in throwing *NotImplementedException*.
// Such situation means either that the method should be 
// implemented, either that what should be a *compile time* 
// error is a *run-time* error *by-design*,
// and this is not good design. Sometime this situation 
// also pinpoints a method stub that can be safely removed.
//
// If *NotImplementedException* is thrown from a method 
// with significant logic, the severity is considered as 
// **Medium**, because often the fix consists in  throwing 
// another exception type, like **InvalidOperationException**.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Override equals and operator equals on value types</Name>
warnif count > 0
from t in JustMyCode.Types where
  t.IsStructure &&
  t.InstanceFields.Count() > 0
let equalsMethod = t.InstanceMethods.Where(m0 => m0.Name == "Equals(Object)").SingleOrDefault()
where equalsMethod == null
select new {
   t,
   t.InstanceFields,
   Debt = (15 + 2*t.InstanceFields.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// For value types, the inherited implementation of *Equals()* uses 
// the Reflection library, and compares the contents of all instances
// fields. Reflection is computationally expensive, and comparing 
// every field for equality might be unnecessary.
//
// If you expect users to compare or sort instances, or use them 
// as hash table keys, your value type should implement *Equals()*.
// In C# and VB.NET, you should also provide an implementation of 
// *GetHashCode()* and of the equality and inequality operators. 
//</Description>

//<HowToFix>
// To fix a violation of this rule, provide an implementation 
// of *Equals()* and *GetHashCode()* and implement the equality 
// and inequality operators.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 15 minutes plus 2 minutes per instance field.
//</HowToFix>]]></Query>
    </Group>
    <Group Name="Architecture" Active="True" ShownInReport="False">
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid namespaces mutually dependent</Name>
warnif count > 0

// Optimization: restraint application assemblies set
// If some namespaces are mutually dependent
//  - They must be declared in the same assembly
//  - The parent assembly must ContainsNamespaceDependencyCycle
from assembly in Application.Assemblies.Where(a => a.ContainsNamespaceDependencyCycle != null && a.ContainsNamespaceDependencyCycle.Value)

// hashset is used to avoid reporting both A <-> B and B <-> A
let hashset = new HashSet<INamespace>()

// Optimization: restraint namespaces set
// If a namespace doesn't have a Level value, it must be in a dependency cycle
// or it must be using directly or indirectly a dependency cycle.
let namespacesSuspect = assembly.ChildNamespaces.Where(n => n.Level == null)

from nA in namespacesSuspect

// Select namespaces mutually dependent with nA
let unused = hashset.Add(nA) // Populate hashset
let namespacesMutuallyDependentWith_nA = nA.NamespacesUsed.Using(nA)
          .Except(hashset) // <-- avoid reporting both A <-> B and B <-> A 
where namespacesMutuallyDependentWith_nA.Count() > 0

from nB in namespacesMutuallyDependentWith_nA

// nA and nB are mutually dependent
// Infer which one is low level and which one is high level,
// for that we need to compute the coupling from A to B
// and from B to A in terms of number of types and methods
// usages involved in the coupling.
let typesOfBUsedByA = nB.ChildTypes.UsedBy(nA).ToArray() // Enumerate once
let couplingA2B = 
   typesOfBUsedByA.Sum(t => t.TypesUsingMe.Count(t1 => t1.ParentNamespace == nA)) +
   typesOfBUsedByA.ChildMethods().Sum(m => m.MethodsCallingMe.Count(m1 => m1.ParentNamespace == nA))

let typesOfAUsedByB = nA.ChildTypes.UsedBy(nB).ToArray() // Enumerate once
let couplingB2A = 
   typesOfAUsedByB.Sum(t => t.TypesUsingMe.Count(t1 => t1.ParentNamespace == nB)) +
   typesOfAUsedByB.ChildMethods().Sum(m => m.MethodsCallingMe.Count(m1 => m1.ParentNamespace == nB))

// The lowLevelNamespace is inferred from the fact that 
// [coupling lowLevel -> highLevel] is lower than [coupling highLevel -> lowLevel]
let lowLevelNamespace = (couplingA2B < couplingB2A) ? nA : nB
let highLevelNamespace = (lowLevelNamespace == nA) ? nB : nA

let highLevelTypesUsed = (lowLevelNamespace == nA) ? typesOfBUsedByA : typesOfAUsedByB
let lowLevelTypesUser = lowLevelNamespace.ChildTypes.UsingAny(highLevelTypesUsed)

let lowLevelTypesMethodsUser = lowLevelTypesUser.Cast<IMember>()
                                                .Concat(lowLevelTypesUser.ChildMethods().Using(highLevelNamespace))
                                                .ToArray()  // Enumerate once

// Make the rule works also when lines of code is not available
let lowLevelNamespaceLoc  = lowLevelNamespace.NbLinesOfCode  ?? (lowLevelNamespace.NbILInstructions  / 7)
let highLevelNamespaceLoc = highLevelNamespace.NbLinesOfCode ?? (highLevelNamespace.NbILInstructions / 7)

let annualInterestPerIssue = 
   // Such issue has at least a Severity.Medium, never a Severity.Low
   Math.Max(Severity.Medium.AnnualInterestThreshold().Value.TotalSeconds, 
            ((3600 + lowLevelNamespaceLoc + highLevelNamespaceLoc) / lowLevelTypesMethodsUser.Length).Value)
   .ToSeconds().ToAnnualInterest()

// Select in details types and methods involved in the coupling lowLevelNamespace using highLevelNamespace
from tmCulprit in lowLevelTypesMethodsUser 
let used =  (tmCulprit.IsType ? tmCulprit.AsType.TypesUsed.Where(t => t.ParentNamespace == highLevelNamespace) :
                                tmCulprit.AsMethod.MembersUsed.Where(m => m.ParentNamespace == highLevelNamespace))
            .ToArray()  // Enumerate once

select new { 
   tmCulprit, 
   shouldntUse = used, 
   becauseNamespace = lowLevelNamespace,
   shouldntUseNamespace = highLevelNamespace,
   Debt = used.Length.Linear(1, 15,   10, 60).ToMinutes().ToDebt(),
   AnnualInterest = annualInterestPerIssue

}
//<Description>
// This rule lists types and methods from a low-level namespace
// that use types and methods from higher-level namespace.
//
// The pair of low and high level namespaces is made of two
// namespaces that use each other.
//
// For each pair of namespaces, to infer which one is low-level
// and which one is high-level, the rule computes the two coupling
// [from A to B] and [from B to A] in terms of number of types, 
// methods and fields involved in the coupling. Typically
// the coupling from low-level to high-level namespace is significantly
// lower than the other legitimate coupling.
//
// Following this rule is useful to avoid **namespaces dependency 
// cycles**. This will get the code architecture close to a 
// *layered architecture*, where *low-level* code is not allowed
// to use *high-level* code.
//
// In other words, abiding by this rule will help significantly
// getting rid of what is often called **spagetthi code:
// Entangled code that is not properly layered and structured**.
//
// More on this in our white books relative to partitioning code.
// http://www.ndepend.com/docs/white-books
//</Description>

//<HowToFix>
// Refactor the code to make sure that **the low-level namespace 
// doesn't use the high-level namespace**.
//
// The rule lists in detail which low-level types and methods 
// shouldn't use which high-level types and methods. The refactoring 
// patterns that help getting rid of each listed dependency include:
//
// • Moving one or several types from the *low-level* namespaces
// to the *high-level* one, or do the opposite.
//
// • Use *Inversion of Control (IoC)*: 
// http://en.wikipedia.org/wiki/Inversion_of_control
// This consists in creating new interfaces in the
// *low-level* namespace, implemented by classes
// in the *high-level* namespace. This way *low-level* 
// code can consume *high-level* code through interfaces, 
// without using directly *high-level* implementations.
// Interfaces can be passed to *low-level* code through
// the *high-level* namespace code, or through even 
// higher-level code. In related documentations 
// you can see these interfaces named as *callbacks*, 
// and the overall pattern is also known as 
// *Dependency Injection (DI)*:
// http://en.wikipedia.org/wiki/Dependency_injection
//
// That rule might not be applicable for frameworks
// that present public namespaces mutually dependent.
// In such situation the cost to break the API can be
// higher than the cost to let the code entangled.
//
// -
//
// The estimated **Debt**, which means the effort to fix such issue
// to make sure that the first namespace doesn't rely anymore
// on the second one, depends on the number of types and methods used.
//
// Because both namespace are now forming a *super-component*
// that cannot be partitioned in smaller components, the cost to 
// unfix each issue is proportional to the size of this super-component.
// As a consequence, the estimated **Annual Interest**, which means 
// the annual cost to let both namespaces mutually dependend, is equal 
// to an hour plus a number of minutes proportional to the size 
// (in lines of code) of both namespaces. The obtained *Annual Interest* 
// value is then divided by the number of detailled issues listed.
//
// Often the estimated *Annual Interest* for each listed issue 
// is higher than the *Debt*, which means that leaving such issue
// unfixed for a year costs more than taking the time to fix issue once.
//
// --
//
// To explore the coupling between the two namespaces mutually 
// dependent:
// 
//  1) from the *becauseNamespace right-click menu* choose
// *Copy to Matrix Columns* to export this low-level namespace
// to the horizontal header of the dependency matrix.
//
//  2) from the *shouldntUseNamespace right-click menu* choose
// *Copy to Matrix Rows* to export this high-level namespace to 
// the vertical header of the dependency matrix.
//
//  3) double-click the black matrix cell (it is black because of
// the mutual dependency).
//
//  4) in the matrix command bar, click the button: 
// *Remove empty Row(s) and Column(s)*.
//
// At this point, the dependency matrix shows types involved 
// into the coupling.
//
// • Blue cells represent types from low-level namespace using types 
// from high-level namespace
//
// • Green cells represent types from high-level namespace using 
// types from low-level namespace
//
// • Black cells represent types from low-level and high-level
// namespaces that use each other.
//
// There are more green cells than blue and black cells because
// green cell represents correct coupling from high-level to low-level.
// **The goal is to eliminate incorrect dependencies represented by 
// blue and black cells.**
//</HowToFix>
      ]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid namespaces dependency cycles</Name>
warnif count > 0

// Optimization: restraint application assemblies set
// If some namespaces are mutually dependent
//  - They must be declared in the same assembly
//  - The parent assembly must ContainsNamespaceDependencyCycle
from assembly in Application.Assemblies
                 .Where(a => a.ContainsNamespaceDependencyCycle != null && 
                             a.ContainsNamespaceDependencyCycle.Value)

// Optimization: restraint namespaces set
// A namespace involved in a cycle necessarily have a null Level.
let namespacesSuspect = assembly.ChildNamespaces.Where(n => n.Level == null)

// hashset is used to avoid iterating again on namespaces already caught in a cycle.
let hashset = new HashSet<INamespace>()


from suspect in namespacesSuspect
   // By commenting in this line, the query matches all namespaces involved in a cycle.
   where !hashset.Contains(suspect)

   // Define 2 code metrics
   // • Namespaces depth of is using indirectly the suspect namespace.
   // • Namespaces depth of is used by the suspect namespace indirectly.
   // Note: for direct usage the depth is equal to 1.
   let namespacesUserDepth = namespacesSuspect.DepthOfIsUsing(suspect)
   let namespacesUsedDepth = namespacesSuspect.DepthOfIsUsedBy(suspect)

   // Select namespaces that are both using and used by namespaceSuspect
   let usersAndUsed = from n in namespacesSuspect where 
                         namespacesUserDepth[n] > 0 && 
                         namespacesUsedDepth[n] > 0 
                      select n

   where usersAndUsed.Count() > 0

   // Here we've found namespace(s) both using and used by the suspect namespace.
   // A cycle involving the suspect namespace is found!
   let cycle = usersAndUsed.Append(suspect)

   // Fill hashset with namespaces in the cycle.
   // .ToArray() is needed to force the iterating process.
   let unused1 = (from n in cycle let unused2 = hashset.Add(n) select n).ToArray()

select new { 
   suspect, 
   cycle,
   Debt = 120.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule lists all *application namespace dependency cycles*.
// Each row shows a different cycle, indexed with one of the namespace entangled 
// in the cycle.
//
// To browse a cycle on the dependency graph or the dependency matrix, right click
// a cycle cell and export the matched namespaces to the dependency graph or matrix.
//
// In the matrix, dependency cycles are represented with red squares and black cells.
// To easily browse dependency cycles, the dependency matrix comes with an option:
// *Display Direct and Indirect Dependencies*
//
// Read our white books relative to partitioning code, 
// to know more about namespaces dependency cycles, and why avoiding them 
// is a *simple yet efficient* solution to clean the architecture of a code base.
// http://www.ndepend.com/docs/white-books
//</Description>

//<HowToFix>
// Removing first pairs of *mutually dependent namespaces* will eliminate
// most *namespaces dependency cycles*. This is why it is recommended
// focusing on matches of the default rule 
// **Avoid namespaces mutually dependent** before dealing
// with the present rule.
//
// Once solving all *mutually dependent namespaces*, remaining cycles
// matched by the present rule necessarily involve 3 or more namespaces
// like in: *A is using B is using C is using A*.
// Such cycle can be broken by identifying which namespace should
// be at the *lower-level*. For example if B should be at the
// *lower-level*, then it means C should be at the *higher-level*
// and to break the cycle, you just have to remove the dependency
// from B to C, with a pattern described in the *HowToFix* section
// of the rule *Avoid namespaces mutually dependent*.
//
// The estimated Debt, which means the effort to fix such issue,
// doesn't depend on the cycle length. First because fixing the rule
// **Avoid namespaces mutually dependent** will fix most cycle reported
// here, second because even a long cycle can be broken by removing
// a few dependency.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid partitioning the code base through many small library Assemblies</Name>
warnif count > 10
from a in Application.Assemblies where
  ( a.NbLinesOfCode < 1000 ||
    a.NbILInstructions < 7000 ) &&
  a.FilePath.FileExtension.ToLower() == ".dll"
select new { 
   a, 
   a.NbLinesOfCode, 
   a.NbILInstructions,
   Debt = 40.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Each .NET Assembly compiled represents one or several physical file(s).
// Having too many library .NET Assemblies is a symptom of 
// considering **physical** .NET Assemblies as **logical** components.
//
// We advise having less, and bigger, .NET Assemblies
// and using the concept of namespaces to define logical components.
// Benefits are:
//
// • Faster compilation time.
//
// • Faster startup time for your program.
//
// • Easier deployment thanks to less files to manage.
//
// • If you are developing a Framework,
// less .NET assemblies to reference and manage for your clients.
//</Description>

//<HowToFix>
// Consider using the *physical* concept of assemblies for physical needs 
// only.
//
// Our white book about **Partitioning code base through .NET assemblies 
// and Visual Studio projects** explains in details valid and invalid
// reasons to use assemblies.
// Download it here:
// http://www.ndepend.com/Res/NDependWhiteBook_Assembly.pdf
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>UI layer shouldn't use directly DB types</Name>
        
warnif count > 0

// UI layer is made of types using a UI framework
let uiTypes = Application.Types.UsingAny(Assemblies.WithNameIn("PresentationFramework", "System.Windows", "System.Windows.Forms", "System.Web"))

// You can easily customize this part to define what are DB types.
let dbTypes = ThirdParty.Assemblies.WithNameIn("System.Data", "EntityFramework", "NHibernate").ChildTypes()
              // Ideally even DataSet and associated, usage should be forbidden from UI layer: 
              // http://stackoverflow.com/questions/1708690/is-list-better-than-dataset-for-ui-layer-in-asp-net
              .Except(ThirdParty.Types.WithNameIn("DataSet", "DataTable", "DataRow"))

from uiType in uiTypes.UsingAny(dbTypes)
let dbTypesUsed = dbTypes.Intersect(uiType.TypesUsed)

let dbTypesAndMembersUsed = dbTypesUsed.Union(dbTypesUsed.ChildMembers().UsedBy(uiType))

// Per defaut this rule estimates a technical debt
// proportional to the coupling between the UI and DB types.
let couplingPerUIType = 2 +
   uiType.Methods.UsingAny(dbTypesUsed).Count() +
   dbTypesAndMembersUsed.Count()

select new { 
   uiType, 
   dbTypesAndMembersUsed,
   Debt = (4 * couplingPerUIType).ToMinutes().ToDebt(),
   Severity = Severity.High
}
      
//<Description>
// This rule is more a *sample rule to adapt to your need*,
// than a rigid rule you should abide by. It shows how to
// define code layers in a rule and how to be warned about  
// layers dependencies violations.
//
// This rule first defines the UI layer and the DB framework 
// layer. Second it checks if any UI layer type is using 
// directly any DB framework layer type.
//
// • The **DB framework layer** is defined as the set of *third-party*
// types in the framework *ADO.NET*, *EntityFramework*, 
// *NHibernate* types, that the application is consuming. 
// It is easy to append and suppress any DB framework.
//
// • The UI layer (**User Interface Layer**) is defined as the
// set of types that use *WPF*, *Windows Form*, *ASP.NET*.
//
// *UI using directly DB frameworks* is generally considered 
// as *poor design* because DB frameworks accesses should be 
// a concept hidden to UI, encapsulated into a **dedicated 
// Data Access Layer (DAL)**.
//
// Notice that per defaut this rule estimates a technical debt
// proportional to the coupling between the UI and DB types. 
//</Description>

//<HowToFix>
// This rule lists precisely which UI type uses which 
// DB framework type. Instead of fixing matches one by one,
// first imagine how DB framework accesses could be 
// encapsulated into a dedicated layer.
//</HowToFix>
]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>UI layer shouldn't use directly DAL layer</Name>
warnif count > 0

// UI layer is made of types using a UI framework
let uiTypes = Application.Types.UsingAny(Assemblies.WithNameIn("PresentationFramework", "System.Windows", "System.Windows.Forms", "System.Web"))

// Exclude commonly used DataSet and associated, from ADO.Net types
// You can easily customize this part to define what are DB types.
let dbTypes = ThirdParty.Assemblies.WithNameIn("System.Data", "EntityFramework", "NHibernate").ChildTypes()
              .Except(ThirdParty.Types.WithNameIn("DataSet", "DataTable", "DataRow"))

// DAL layer is made of types using a DB framework
// .ToHashSet() results to faster execution of    dalTypes.Intersect(uiType.TypesIUse).
let dalTypes = Application.Types.UsingAny(dbTypes).ToHashSet()

from uiType in uiTypes.UsingAny(dalTypes)
let dalTypesUsed = dalTypes.Intersect(uiType.TypesUsed)

let dalTypesAndMembersUsed = dalTypesUsed.Union(dalTypesUsed.ChildMembers().UsedBy(uiType))

// Per defaut this rule estimates a technical debt
// proportional to the coupling between the UI with the DAL layer. 
let couplingPerUIType = 2 +
   uiType.Methods.UsingAny(dalTypesUsed).Count() +
   dalTypesAndMembersUsed.Count()

select new {
   uiType,
   // if dalTypesUsed is empty, it means that the uiType is part of the DAL
   dalTypesAndMembersUsed,
   Debt = (4 * couplingPerUIType).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is more a *sample rule to adapt to your need*,
// than a rigid rule you should abide by. It shows how to
// define code layers in a rule and how to be warned about 
// layers dependencies violations.
//
// This rule first defines the UI layer and the DAL layer.
// Second it checks if any UI layer type is using directly
// any DAL layer type.
//
// • The DB layer (the DAL, **Data Access Layer**) is defined as 
// the set of types of the application that use *ADO.NET*, 
// *EntityFramework*, *NHibernate* types. It is easy to append 
// and suppress any DB framework.
//
// • The UI layer (**User Interface Layer**) is defined as the
// set of types that use *WPF*, *Windows Form*, *ASP.NET*.
//
// *UI using directly DAL* is generally considered as *poor 
// design* because DAL accesses should be a concept
// hidden to UI, encapsulated into an **intermediary domain 
// logic**.
//
// Notice that per defaut this rule estimates a technical debt
// proportional to the coupling between the UI with the DAL layer. 
//</Description>

//<HowToFix>
// This rule lists precisely which UI type uses which DAL type.
//
// More about this particular design topic here:
// http://www.kenneth-truyers.net/2013/05/12/the-n-layer-myth-and-basic-dependency-injection/
//</HowToFix>
]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Assemblies with poor cohesion (RelationalCohesion)</Name>
warnif count > 0 from a in Application.Assemblies 

// Build the types list on which we want to check cohesion
// This is the assembly 'a' type, minus enumeration
// and types generated by the compiler.
let types = a.ChildTypes.Where(
   t => !t.IsGeneratedByCompiler &&
        !t.IsEnumeration)
        // Absolutly need ToHashet() to have fast Intersect() calls below.
        .ToHashSet()

// Relational Cohesion metrics is relevant only if there are enough types
where types.LongCount()> 20

// R is the total number of relationship between types of the assemblies. 
let R = types.Sum(t => t.TypesUsed.Intersect(types).Count())

// Relational Cohesion formula
let relationalCohesion = (double)R / types.Count
where  
  
  (relationalCohesion  < 1.5 || 
   relationalCohesion  > 4.0)
select new { 
  a, 
  a.ChildTypes,
  relationalCohesion, 
  a.RelationalCohesion,
  Debt = 10.ToMinutes().ToDebt(),
  Severity = Severity.Low
}

//<Description>
// This rule computes the *Relational Cohesion* metric for
// the application assemblies, and warns about wrong values.
// 
// The *Relational Cohesion* for an assembly, is the total number 
// of relationship between types of the assemblies, divided 
// by the number of types. In other words it is the average
// number of types in the assembly used by a type in the assembly.
//
// As classes inside an assembly should be strongly related, 
// the cohesion should be high. On the other hand, a value 
// which is too high may indicate over-coupling. A good range 
// for *Relational Cohesion* is **1.5 to 4.0**.
//
// Notice that assemblies with less than 20 types are ignored.
//</Description>

//<HowToFix>
// Matches of this present rule might reveal either assemblies
// with specific coding constraints (like code generated that
// have particular structure) either issues in design.
//
// In the second case, large refactoring can be planned
// not to respect this rule in particular, but to increase
// the overall design and code maintainability.
//
// The severity of issues of this rule is **Low** because
// the code metric *Relational Cohesion* is an information 
// about the code structure state but **is not actionable**, 
// it doesn't tell precisely what to do obtain a better score.
//
// Fixing actionable issues of others **Architecture** and 
// **Code Smells** default rules will necessarily increase 
// the *Relational Cohesion* scores.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Namespaces with poor cohesion (RelationalCohesion)</Name>
warnif count > 0 from n in Application.Namespaces 

// Build the types list on which we want to check cohesion
// This is the namespace children types, minus enumerations
// and types generated by the compiler.
let types = n.ChildTypes.Where(
   t => !t.IsGeneratedByCompiler &&
        !t.IsEnumeration)
        // Absolutly need ToHashet() to have fast Intersect() calls below.
        .ToHashSet()

// Relational Cohesion metrics is relevant only if there are enough types
where types.LongCount() > 20

// R is the total number of relationship between types of the namespaces. 
let R = types.Sum(t => t.TypesUsed.Intersect(types).Count())

// Relational Cohesion formula
let relationalCohesion = (double)R / types.Count
where  
  (relationalCohesion  < 1.5 || 
   relationalCohesion  > 4.0)
select new { 
  n, 
  n.ChildTypes,
  relationalCohesion,
  Debt = 10.ToMinutes().ToDebt(),
  Severity = Severity.Low
}

//<Description>
// This rule computes the *Relational Cohesion* metric for
// the application namespaces, and warns about wrong values.
// 
// The *Relational Cohesion* for a namespace, is the total number 
// of relationship between types of the namespaces, divided 
// by the number of types. In other words it is the average
// number of types in the namespace used by a type in the namespace.
//
// As classes inside an namespace should be strongly related, 
// the cohesion should be high. On the other hand, a value 
// which is too high may indicate over-coupling. A good range 
// for *Relational Cohesion* is **1.5 to 4.0**.
//
// Notice that namespaces with less than 20 types are ignored.
//</Description>

//<HowToFix>
// Matches of this present rule might reveal either namespaces
// with specific coding constraints (like code generated that
// have particular structure) either issues in design.
//
// In the second case, refactoring sessions can be planned
// to increase the overall design and code maintainability.
//
// The severity of issues of this rule is **Low** because
// the code metric *Relational Cohesion* is an information 
// about the code structure state but **is not actionable**, 
// it doesn't tell precisely what to do obtain a better score.
//
// Fixing actionable issues of others **Architecture** and 
// **Code Smells** default rules will necessarily increase 
// the *Relational Cohesion* scores.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Assemblies that don't satisfy the Abstractness/Instability principle</Name>
warnif count > 0 from a in Application.Assemblies 
  where a.NormDistFromMainSeq > 0.7
  orderby a.NormDistFromMainSeq descending
select new { 
   a,
   a.NormDistFromMainSeq,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// The **Abstractness versus Instability Diagram** that is shown in the NDepend 
// report helps to assess which assemblies are **potentially painful to maintain**
// (i.e concrete and stable) and which assemblies are **potentially useless** 
// (i.e abstract and instable).
//
// • **Abstractness**: If an assembly contains many abstract types 
// (i.e interfaces and abstract classes) and few concrete types, 
// it is considered as abstract.
//
// • **Stability**: An assembly is considered stable if its types 
// are used by a lot of types from other assemblies. In this context 
// stable means *painful to modify*.
//
// From these metrics, we define the *perpendicular normalized distance of
// an assembly from the idealized line* **A + I = 1** (called *main sequence*). 
// This metric is an indicator of the assembly's balance between abstractness 
// and stability. We precise that the word *normalized* means that the range 
// of values is [0.0 … 1.0].
//
// This rule warns about assemblies with a *normalized distance* greater than 
// than 0.7.
//
// This rules use the default code metric on assembly
// *Normalized Distance from the Main Sequence* explained here: 
// http://www.ndepend.com/docs/code-metrics#DitFromMainSeq
//
// These concepts have been originally introduced by *Robert C. Martin*
// in 1994 in this paper: http://www.objectmentor.com/resources/articles/oodmetrc.pdf
//</Description>

//<HowToFix>
// Violations of this rule indicate assemblies with an improper 
// *abstractness / stability* balance.
//
// • Either the assembly is *potentially painful to maintain* (i.e is massively
// used and contains mostly concrete types). This can be fixed by creating 
// abstractions to avoid too high coupling with concrete implementations.
//
// • Either the assembly is *potentially useless* (i.e contains mostly
// abstractions and is not used enough). In such situation, the design
// must be reviewed to see if it can be enhanced.
//
// The severity of issues of this rule is **Low** because
// the *Abstractness/Instability principle* is an information 
// about the code structure state but **is not actionable**, 
// it doesn't tell precisely what to do obtain a better score.
//
// Fixing actionable issues of others **Architecture** and 
// **Code Smells** default rules will necessarily push 
// the *Abstractness/Instability principle* scores in the 
// right direction.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Higher cohesion - lower coupling</Name>
// warnif count > 0 
let abstractNamespaces = JustMyCode.Namespaces.Where(
     n => n.ChildTypes.Where(t => !t.IsInterface && !t.IsEnumeration && !t.IsDelegate).Count() == 0
).ToHashSet()

let concreteNamespaces = JustMyCode.Namespaces.Except(abstractNamespaces).ToHashSet()

from n in concreteNamespaces
let namespacesUsed = n.NamespacesUsed.ExceptThirdParty()
let concreteNamespacesUsed = namespacesUsed.Except(abstractNamespaces)
let abstractNamespacesUsed = namespacesUsed.Except(concreteNamespaces)
orderby concreteNamespacesUsed.Count() descending
select new { 
   n, 
   concreteNamespacesUsed , 
   abstractNamespacesUsed,
   // Debt = 50.ToMinutes().ToDebt(),
   // Severity = Severity.High
}

//<Description>
// It is deemed as a good software architecture practice to clearly separate
// *abstract* namespaces that contain only abstractions (interfaces, enumerations, delegates)
// from *concrete* namespaces, that contain classes and structures.
//
// Typically, the more concrete namespaces rely on abstract namespaces *only*,
// the more **Decoupled** is the architecture, and the more **Cohesive** are 
// classes inside concrete namespaces.
//
// The present code query defines sets of abstract and concrete namespaces
// and show for each concrete namespaces, which concrete and abstract namespaces 
// are used. 
//</Description>

//<HowToFix>
// This query can be transformed into a code rule, depending if you wish to 
// constraint your code structure *coupling / cohesion* ratio.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Example of custom rule to check for dependency</Name>
warnif count > 0 from a in Assemblies
where 
a.IsUsing("Foo1.Foo2".AllowNoMatch().MatchNamespace()) &&
(a.Name == @"Foo3")
select new { 
   a, 
   a.NbLinesOfCode,
   // Debt and Severity / Annual Interest can be modified to estimate well the
   // effort to fix the issue and the annual cost to leave the issue unfixed.
   Debt = 30.ToMinutes().ToDebt(),
   Severity = Severity.High
}
// the assembly Foo3
// shouldn't use directly 
// the namespace Foo3.Foo4
// because (TODO insert your reason)

//<Description>
// This rule is a **sample rule** that shows how to
// check if a particular dependency exists or not, 
// from a code element **A** to a code element **B**,
// **A** and **B** being an *Assembly*, a *Namespace*, a *Type*, 
// a *Method* or a *Field*, **A** and **B** being not 
// necessarily of same kind (i.e two Assemblies or 
// two Namespaces…).
//
// Such rule can be generated:
//
// • by right clicking the cell in the *Dependency Matrix* 
// with **B** in row and **A** in column,
//
// • or by right-clicking the concerned arrow in the *Dependency 
// Graph* from **A** to **B**,
//
// and in both cases, click the menu
// **Generate a code rule that warns if this dependency exists**
//
// The generated rule will look like this one.
// It is now up to you to adapt this rule to check exactly 
// your needs.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
    </Group>
    <Group Name="API Breaking Changes" Active="True" ShownInReport="True">
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>API Breaking Changes: Types</Name>

warnif count > 0 from t in codeBase.OlderVersion().Application.Types
where t.IsPubliclyVisible && 

     // The type has been removed, it was not tagged as obsolete
     // and its parent assembly hasn't been removed …
     ( ( t.WasRemoved() && 
        !t.ParentAssembly.WasRemoved() && 
        !t.IsObsolete) ||

     // … or the type is not publicly visible anymore
        !t.WasRemoved() && !t.NewerVersion().IsPubliclyVisible)

select new { 
   t,
   NewVisibility = 
      (t.WasRemoved() ? " " : 
       t.NewerVersion().Visibility.ToString()),
   Debt = 20.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule warns if a type publicly visible in the *baseline*, 
// is not publicly visible anymore or if it has been removed.
// Clients code using such type will be broken.
//</Description>

//<HowToFix>
// Make sure that public types that used to be presented to
// clients, still remain public now, and in the future.
//
// If a public type must really be removed, you can tag it
// with *System.ObsoleteAttribute* with a *workaround message*
// during a few public releases, until it gets removed definitely.
// Notice that this rule doesn't match types removed that were
// tagged as obsolete.
//
// Issues of this rule have a severity equal to **High**
// because an API Breaking change can provoque significant
// friction with consumers of the API.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>API Breaking Changes: Methods</Name>
warnif count > 0 from m in codeBase.OlderVersion().Application.Methods
where m.IsPubliclyVisible && 

     // The method has been removed, it was not tagged as obsolete
     // and its parent type hasn't been removed …
     ( ( m.WasRemoved() && 
        !m.ParentType.WasRemoved() && 
        !m.IsObsolete )

        // … or the method is not publicly visible anymore
     || (!m.WasRemoved() && !m.NewerVersion().IsPubliclyVisible) 

        // … or the method return type has changed
     || (!m.WasRemoved() && m.ReturnType != null && m.NewerVersion().ReturnType != null
                         && m.ReturnType.FullName != m.NewerVersion().ReturnType.FullName)        
      )

//--------------------------------------
// Handle special case: if between two versions a regular property becomes 
// an auto-property (or vice-versa) the property getter/setter method have 
// a different value for IMethod.IsGeneratedByCompiler
// since auto-property getter/setter are marked as generated by the compiler.
//
// If a method IsGeneratedByCompiler value changes between two versions, 
// NDepend doesn't pair the newer/older occurences of the method.
//
// Hence in such situation, a public method is seen as added 
// and a public method is seen as removed, but the API is not broken!
// The equivalentMethod-check below avoids reporting such 
// API Breaking Change false-positive.
let equivalentMethod = m.WasRemoved() && m.ParentType.IsPresentInBothBuilds() ?
   m.ParentType.NewerVersion().Methods
   .FirstOrDefault(m1 => 
       m1.IsPubliclyVisible &&
       m1.Name == m.Name &&
       m1.IsGeneratedByCompiler != m.IsGeneratedByCompiler &&
      (m1.ReturnType == null || m.ReturnType == null || m1.ReturnType.FullName == m.ReturnType.FullName)
    )
    : null
where equivalentMethod == null
//--------------------------------------


select new { 
   m,
   NewVisibility = 
      (m.WasRemoved() ? " " : 
       m.NewerVersion().Visibility.ToString()),
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule warns if a method publicly visible in the *baseline*, 
// is not publicly visible anymore or if it has been removed.
// Clients code using such method will be broken.
//</Description>

//<HowToFix>
// Make sure that public methods that used to be presented to
// clients, still remain public now, and in the future.
//
// If a public method must really be removed, you can tag it
// with *System.ObsoleteAttribute* with a *workaround message*
// during a few public releases, until it gets removed definitely.
// Notice that this rule doesn't match methods removed that were
// tagged as obsolete.
//
// Issues of this rule have a severity equal to **High**
// because an API Breaking change can provoque significant
// friction with consumers of the API.
//</HowToFix>
]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>API Breaking Changes: Fields</Name>
warnif count > 0 from f in codeBase.OlderVersion().Application.Fields
where f.IsPubliclyVisible &&

     // The field has been removed, it was not tagged as obsolete
     // and its parent type hasn't been removed …
     ( ( f.WasRemoved() && 
        !f.ParentType.WasRemoved() && 
        !f.IsObsolete)

     // … or the field is not publicly visible anymore
     ||  !f.WasRemoved() && !f.NewerVersion().IsPubliclyVisible)

     // … or the field type has changed
     || (!f.WasRemoved() && f.FieldType != null && f.NewerVersion().FieldType != null
                         && f.FieldType.FullName != f.NewerVersion().FieldType.FullName)

select new { 
   f,
   NewVisibility = 
      (f.WasRemoved() ? " " : 
       f.NewerVersion().Visibility.ToString()),
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule warns if a field publicly visible in the *baseline*, 
// is not publicly visible anymore or if it has been removed.
// Clients code using such field will be broken.
//</Description>

//<HowToFix>
// Make sure that public fields that used to be presented to
// clients, still remain public now, and in the future.
//
// If a public field must really be removed, you can tag it
// with *System.ObsoleteAttribute* with a *workaround message*
// during a few public releases, until it gets removed definitely.
// Notice that this rule doesn't match fields removed that were
// tagged as obsolete.
//
// Issues of this rule have a severity equal to **High**
// because an API Breaking change can provoque significant
// friction with consumers of the API.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>API Breaking Changes: Interfaces and Abstract Classes</Name>
warnif count > 0 from tNewer in Application.Types where 
 (tNewer.IsInterface || tNewer.IsClass && tNewer.IsAbstract) && 
  tNewer.IsPubliclyVisible && 
  tNewer.IsPresentInBothBuilds()

let tOlder = tNewer.OlderVersion() where tOlder.IsPubliclyVisible

let methodsRemoved = tOlder.Methods.Where(m => m.IsAbstract && m.WasRemoved())
let methodsAdded = tNewer.Methods.Where(m => m.IsAbstract && m.WasAdded())

where methodsAdded.Count() > 0 || methodsRemoved.Count() > 0
select new { 
   tNewer, 
   methodsAdded, 
   methodsRemoved,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule warns if a publicly visible interface or abstract class 
// has been changed and contains new abstract methods or 
// if some abstract methods have been removed.
//
// Clients code that implement such interface or derive from 
// such abstract class will be broken.
//</Description>

//<HowToFix>
// Make sure that the public contracts of interfaces and abstract classes
// that used to be presented to clients, remain stable now, and in the future.
//
// If a public contract must really be changed, you can tag 
// abstract methods that will be removed with *System.ObsoleteAttribute*  
// with a *workaround message* during a few public releases, until it gets 
// removed definitely.
//
// Issues of this rule have a severity equal to **High**
// because an API Breaking change can provoque significant
// friction with consummers of the API.
// The severity is not set to **Critical** because an interface 
// is not necessarily meant to be implemented by the consummer
// of the API.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Broken serializable types</Name>
warnif count > 0

from t in Application.Types where

  // Collect types tagged with SerializableAttribute
  t.HasAttribute("System.SerializableAttribute".AllowNoMatch())  && 
 !t.IsDelegate &&
  t.IsPresentInBothBuilds() &&
  t.HasAttribute(t)

  // Find newer and older versions of NonSerializedAttribute
  let newNonSerializedAttribute = ThirdParty.Types.WithFullName("System.NonSerializedAttribute").SingleOrDefault()
  let oldNonSerializedAttribute = newNonSerializedAttribute == null ? null : newNonSerializedAttribute.OlderVersion()

  // Find added or removed fields not marked with NonSerializedAttribute
  let addedInstanceField = from f in t.InstanceFields where 
                             f.WasAdded() && 
                             (newNonSerializedAttribute == null || !f.HasAttribute(newNonSerializedAttribute))
                           select f
  let removedInstanceField = from f in t.OlderVersion().InstanceFields where 
                             f.WasRemoved() && 
                             (oldNonSerializedAttribute == null || !f.HasAttribute(oldNonSerializedAttribute))
                           select f
  where addedInstanceField.Count() > 0 || removedInstanceField.Count() > 0

select new { 
   t, 
   addedInstanceField, 
   removedInstanceField,
   Debt = 20.ToMinutes().ToDebt(),
   Severity = Severity.Critical
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule warns about breaking changes in types tagged with 
// *SerializableAttribute*.
//
// To do so, this rule searches for serializable type with serializable 
// instance fields added or removed. Notice that it doesn't take account
// of fields tagged with *NonSerializedAttribute*.
//
// From http://msdn.microsoft.com/library/system.serializableattribute.aspx :
// "All the public and private fields in a type that are marked by the 
//  *SerializableAttribute*  are serialized by default, unless the type 
//  implements the *ISerializable* interface to  override the serialization process. 
//  The default serialization process excludes fields that are marked 
//  with the *NonSerializedAttribute* attribute."
//</Description>

//<HowToFix>
// Make sure that the serialization process of serializable types remains
// stable now, and in the future.
// 
// Else you'll have to deal with **Version Tolerant Serialization**
// that is explained here:
// https://msdn.microsoft.com/en-us/library/ms229752(v=vs.110).aspx
//
// Issues of this rule have a severity equal to **High**
// because an API Breaking change can provoque significant
// friction with consummers of the API.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid changing enumerations Flags status</Name>
warnif count > 0 

let oldFlags = codeBase.OlderVersion().ThirdParty.Types.WithFullName("System.FlagsAttribute").SingleOrDefault()
let newFlags = ThirdParty.Types.WithFullName("System.FlagsAttribute").SingleOrDefault()
where oldFlags != null && newFlags != null

from t in Application.Types where
   t.IsEnumeration &&
   t.IsPresentInBothBuilds() 
let hasFlagsAttributeNow = t.HasAttribute(newFlags)
let usedToHaveFlagsAttribute = t.OlderVersion().HasAttribute(oldFlags) 
where hasFlagsAttributeNow != usedToHaveFlagsAttribute
select new { 
   t, 
   hasFlagsAttributeNow, 
   usedToHaveFlagsAttribute,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule matches enumeration types that used to be tagged
// with *FlagsAttribute* in the *baseline*, and not anymore.
// It also matches the opposite, enumeration types that are now
// tagged with *FlagsAttribute*, and were not tagged in the *baseline*.
//
// Being tagged with *FlagsAttribute* is a strong property for an enumeration.
// Not so much in terms of *behavior* (only the *enum.ToString()* method
// behavior changes when an enumeration is tagged with *FlagsAttribute*)
// but in terms of *meaning*: is the enumeration a **range of values**
// or a **range of flags**?
//
// As a consequence, changing the *FlagsAttribute*s status of an enumeration can 
// have significant impact for its clients.
//</Description>

//<HowToFix>
// Make sure the *FlagsAttribute* status of each enumeration remains stable
// now, and in the future.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>API: New publicly visible types</Name>
from t in Application.Types
where t.IsPubliclyVisible && 

     // The type has been removed and its parent assembly hasn't been removed …
     ( (t.WasAdded() && !t.ParentAssembly.WasAdded()) ||

     // … or the type existed but was not publicly visible
       !t.WasAdded() && !t.OlderVersion().IsPubliclyVisible)

select new { 
   t,
   OldVisibility = 
      (t.WasAdded() ? " " : 
       t.OlderVersion().Visibility.ToString()),
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists types that are new in the public 
// surface of the analyzed assemblies.
//</Description>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>API: New publicly visible methods</Name>
from m in Application.Methods
where m.IsPubliclyVisible && 

     // The method has been removed and its parent assembly hasn't been removed …
     ( (m.WasAdded() && !m.ParentType.WasAdded()) ||

     // … or the method existed but was not publicly visible
       !m.WasAdded() && !m.OlderVersion().IsPubliclyVisible)

//--------------------------------------
// Handle special case: if between two versions a regular property becomes 
// an auto-property (or vice-versa) the property getter/setter method have 
// a different value for IMethod.IsGeneratedByCompiler
// since auto-property getter/setter are marked as generated by the compiler.
//
// If a method IsGeneratedByCompiler value changes between two versions, 
// NDepend doesn't pair the newer/older occurences of the method.
//
// Hence in such situation, a public method is seen as added 
// and a public method is seen as removed, but the API is not broken!
// The equivalentMethod-check below avoids reporting such 
// API Breaking Change false-positive.
let equivalentMethod = m.WasAdded() && m.ParentType.IsPresentInBothBuilds() ?
   m.ParentType.OlderVersion().Methods
   .FirstOrDefault(m1 => 
       m1.IsPubliclyVisible &&
       m1.Name == m.Name &&
       m1.IsGeneratedByCompiler != m.IsGeneratedByCompiler)
    : null
where equivalentMethod == null
//--------------------------------------

select new { 
   m,
   OldVisibility = 
      (m.WasAdded() ? " " : 
       m.OlderVersion().Visibility.ToString())
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists methods that are new in the public 
// surface of the analyzed assemblies.
//</Description>
]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>API: New publicly visible fields</Name>
from f in Application.Fields
where f.IsPubliclyVisible && 

     // The method has been removed and its parent assembly hasn'f been removed …
     ( (f.WasAdded() && !f.ParentType.WasAdded()) ||

     // … or the t existed but was not publicly visible
       !f.WasAdded() && !f.OlderVersion().IsPubliclyVisible)

select new { 
   f,
   OldVisibility = 
      (f.WasAdded() ? " " : 
       f.OlderVersion().Visibility.ToString())
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists fields that are new in the public 
// surface of the analyzed assemblies.
//</Description>]]></Query>
    </Group>
    <Group Name="Code Coverage" Active="True" ShownInReport="True">
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Code should be tested</Name>
warnif count > 0

// This lambda infers a factor in the range [0,1] from a sequence of distinct types used,
// based on how many of these types are actually concrete (i.e are not interfaces or enumeration).
// Primitive types (int, bool...) are eliminated from the sequence of types used 
// by filtering types declared in the namespace System.
let abstractionUsageFactorFormula = new Func<IEnumerable<IType>,double>(typesUsed => 
            typesUsed.Count(t => t.ParentNamespace.Name != "System" && !t.IsInterface && !t.IsEnumeration) 
     / (1 + typesUsed.Count(t => t.ParentNamespace.Name != "System")))


from method in Application.Methods
  where !method.IsExcludedFromCoverage && method.NbLinesOfCode >= 0 && method.PercentageCoverage < 100 

  // Factor in case method is partially covered
  let uncoverageFactor = ((100 - method.PercentageCoverage) / 100).Value

  // Complexity factor
  let complexityFactor = ((method.CyclomaticComplexity ?? method.ILCyclomaticComplexity) + method.ILNestingDepth).Linear(0, 0.1,    10, 1).Value

  // Not my code is often generated code and is in general easier to get tested since test can be generated as well.
  let justMyCodeFactor = (JustMyCode.Contains(method) ? 1 : 0.4)

  // abstractionUsageFactor reflects the fact that code that relies on interfaces
  // is easier to test that code that relies on concrete classes.
  let abstractionUsageFactor = 0.7 + 0.3 *abstractionUsageFactorFormula(method.MembersUsed.Select(m => m.ParentType).Distinct())

  // The usageFactor depends on the method 'rank' that is a value
  // indicating if the method is often used or not
  let usageFactor = (method.Rank / (method.Rank + 4)).Value

  // It is more complicated to write tests for non publicly visible methods
  let visibilityFactor = method.Visibility.EqualsAny(Visibility.Public, Visibility.Internal) ? 1 : 
                         method.Visibility != Visibility.Private ? 1.1 : 1.2
  
  // Is is more complicated to write tests for methods that read mutable static fields 
  // whose changing state is shared across tests executions.
  let staticFieldUsageFactor = method.ReadsMutableTypeState ? 1.3 : 1.0


  // Both "effort to write tests" and "annual cost to not test" for a method
  // is determined by several factors in the range [0,1] that multiplies the effortToDevelop
  let effortToDevelopInMinutes = method.EffortToDevelop().Value.TotalMinutes

  let effortToWriteTests = Math.Max(2, // Minimum 2 minutes per method not tested
        effortToDevelopInMinutes * 
        uncoverageFactor * 
        complexityFactor * 
        justMyCodeFactor * 
        abstractionUsageFactor * 
        visibilityFactor *
        staticFieldUsageFactor).ToMinutes().ToDebt()

  let annualCostToNotFix = Math.Max(2, // Minimum 2 minutes per method not tested
        effortToDevelopInMinutes * 
        usageFactor *
        uncoverageFactor * 
        justMyCodeFactor).ToMinutes().ToAnnualInterest()
 
  orderby annualCostToNotFix.Value descending

select new { 
  method, 
  method.PercentageCoverage,
  method.NbLinesOfCode,
  method.NbLinesOfCodeNotCovered,
  method.CyclomaticComplexity,
  Debt = effortToWriteTests, 
  AnnualInterest = annualCostToNotFix,

  // BreakingPoint = effortToWriteTests.BreakingPoint(annualCostToNotFix),

  // Uncomment the line below to tinker with various factors
  //  uncoverageFactor, complexityFactor , justMyCodeFactor , abstractionUsageFactor, visibilityFactor, staticFieldUsageFactor 
}


//<Description>
// This rule lists methods not covered at all by test
// or partially covered by tests.
//
// For each match, the rules estimates the **technical debt**, i.e
// the effort to write unit and integration tests for the method.
// The estimation is based on the effort to develop the code element
// multiplied by factors in the range ]0,1.3] based on 
//
// • the method code size and complexity
//
// • the actual percentage coverage
//
// • the abstracness of types used, because relying on classes instead of 
// interfaces makes the code more difficult to test
//
// • the method visibility because testing private or protected
// methods is more difficult than testing public and internal ones
//
// • the fields used by the method, because is is more complicated to 
// write tests for methods that read mutable static fields whose changing 
// state is shared across tests executions.
//
// • whether the method is considered *JustMyCode* or not because *NotMyCode*
// is often generated easier to get tested since tests can be generated as well.
//
// This rule is necessarily a large source of technical debt, since
// the code left untested is by definition part of the technical debt.
//
// This rule also estimates the **annual interest**, i.e the annual cost 
// to let the code uncovered, based on the effort to develop the 
// code element, multiplied by factors based on usage of the code element.
//</Description>

//<HowToFix>
// Write unit tests to test and cover the methods and their parent classes
// matched by this rule.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New Methods should be tested</Name>
warnif count > 0
from m in Application.Methods where
  m.NbLinesOfCode > 0 &&
  m.PercentageCoverage < 30 && 
  m.WasAdded() 
  orderby m.NbLinesOfCode descending, 
           m.NbLinesOfCodeNotCovered ,
           m.PercentageCoverage
select new { 
   m, 
   m.PercentageCoverage, 
   m.NbLinesOfCode, 
   m.NbLinesOfCodeNotCovered,

   // Simplistic Debt estimation, because the effort to write tests for a method not 100% tested
   // is already estimated properly with the rule "Code should be tested".
   Debt = m.NbLinesOfCodeNotCovered.Linear(1,2, 10,10).ToMinutes().ToDebt(),

   Severity = Severity.High
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
// This rule operates only on methods added or refactored since the baseline.
//
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// It is important to write code mostly covered by tests 
// to achieve *maintainable* and *non-error-prone* code.
//
// In real-world, many code bases are poorly covered by tests.
// However it is not practicable to stop the development for months
// to refactor and write tests to achieve high code coverage ratio.
//
// Hence it is recommended that each time a method (or a type) gets added,
// the developer takes the time to write associated unit-tests to cover it.
//
// Doing so will help to increase significantly the maintainability of the code base.
// You'll notice that quickly, refactoring will also be driven by testability, 
// and as a consequence, the overall code structure and design will increase as well.
//
// Issues of this rule have a **High** severity because they reflect
// an actual trend to not care about writing tests on refactored code.
//</Description>

//<HowToFix>
// Write unit-tests to cover the code of most methods and classes added.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods refactored should be tested</Name>
warnif count > 0
from m in Application.Methods where 
  m.PercentageCoverage < 30 && 
  m.CodeWasChanged() 
  orderby m.NbLinesOfCode descending, 
           m.NbLinesOfCodeNotCovered ,
           m.PercentageCoverage
select new {
   m, 
   m.PercentageCoverage,
   m.NbLinesOfCode, 
   m.NbLinesOfCodeNotCovered,

   // Simplistic Debt estimation, because the effort to write tests for a method not 100% tested
   // is already estimated properly with the rule "Code should be tested".
   Debt = m.NbLinesOfCodeNotCovered.Linear(1,2, 10,10).ToMinutes().ToDebt(),

   Severity = Severity.High
}  

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
// This rule operates only on methods added or refactored since the baseline.
//
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// It is important to write code mostly covered by tests 
// to achieve *maintainable* and *non-error-prone* code.
//
// In real-world, many code bases are poorly covered by tests.
// However it is not practicable to stop the development for months
// to refactor and write tests to achieve high code coverage ratio.
//
// Hence it is recommended that each time a method (or a type) gets refactored,
// the developer takes the time to write associated unit-tests to cover it.
//
// Doing so will help to increase significantly the maintainability of the code base.
// You'll notice that quickly, refactoring will also be driven by testability, 
// and as a consequence, the overall code structure and design will increase as well.
//
// Issues of this rule have a **High** severity because they reflect
// an actual trend to not care about writing tests on refactored code.
//</Description>

//<HowToFix>
// Write unit-tests to cover the code of most methods and classes refactored.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Assemblies Namespaces and Types should be tested</Name>
warnif count > 0
from elem in CodeElementParents
where elem.NbLinesOfCode > 0 &&
      elem.PercentageCoverage == 0 && 
      elem.Parent.PercentageCoverage != 0
orderby elem.NbLinesOfCode descending
select new { 
   elem, 
   elem.NbLinesOfCodeNotCovered,
   Debt = 4.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// This rule lists assemblies, namespaces and types that are not
// covered at all by unit tests.
//
// If a parent is matched its children are not matched. For example
// if a namespace is matched, its child types are not matched.
//
// This rule goal is not to collide with the **Code should be tested**
// rule that lists uncovered code for each method and infer the effort
// to write unit tests (the *Debt*) and the annual cost to let the code
// untested (the Annual Interest).
//
// This rule goal is to inform of large code elements left untested.
// As a consequence the *Debt* per issue is only 4 minutes and the
// severity of the issues is *Low*.
//</Description>
//
//<HowToFix>
// Write unit and integration tests to cover, even partially, 
// code elements matched by this rule.
//
// Then use issues of the rules **Code should be tested**,
// **New Methods should be tested** and 
// **Methods refactored should be tested**
// to write more tests where it matters most, and eventually
// refactor some code to make it more testable.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types almost 100% tested should be 100% tested</Name>
warnif count > 0
from t in Application.Types where 
  t.PercentageCoverage >= 95 && 
  t.PercentageCoverage <= 99 &&
 !t.IsGeneratedByCompiler

  let methodsCulprit = t.Methods.Where(m => m.PercentageCoverage < 100)

  orderby t.NbLinesOfCode descending , 
           t.NbLinesOfCodeNotCovered ,
           t.PercentageCoverage
select new { 
   t, 
   t.PercentageCoverage,
   t.NbLinesOfCode, 
   t.NbLinesOfCodeNotCovered, 
   methodsCulprit,

   // Simplistic Debt estimation, because the effort to write tests for a type not 100% tested
   // is already estimated properly with the rule "Code should be tested".
   Debt = t.NbLinesOfCodeNotCovered.Linear(1,2, 20,20).ToMinutes().ToDebt(),

   Severity = Severity.High
} 

//<Description>
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// Often covering the few percents of remaining uncovered code of a class, 
// requires as much work as covering the first 90%.
// For this reason, often teams estimate that 90% coverage is enough.
// However *untestable code* usually means *poorly written code* 
// which usually leads to *error prone code*.
// So it might be worth refactoring and making sure to cover the few uncovered lines of code
// **because most tricky bugs might come from this small portion of hard-to-test code**.
//
// Not all classes should be 100% covered by tests (like UI code can be hard to test)
// but you should make sure that most of the logic of your application
// is defined in some *easy-to-test classes*, 100% covered by tests.
//
// Issues of this rule have a **High** severity because as explained,
// such situation is *bug-prone*.
//</Description>

//<HowToFix>
// Write more unit-tests dedicated to cover code not covered yet.
// If you find some *hard-to-test code*, it is certainly a sign that this code
// is not *well designed* and hence, needs refactoring.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Namespaces almost 100% tested should be 100% tested</Name>
warnif count > 0
from n in Application.Namespaces where 
  n.PercentageCoverage >= 95 && 
  n.PercentageCoverage <= 99 

  let methodsCulprit = n.ChildMethods.Where(m => m.PercentageCoverage < 100)

  orderby n.NbLinesOfCode descending , 
           n.NbLinesOfCodeNotCovered ,
           n.PercentageCoverage
select new { 
   n, 
   n.PercentageCoverage, 
   n.NbLinesOfCode, 
   n.NbLinesOfCodeNotCovered, 
   methodsCulprit,

   // Simplistic Debt estimation, because the effort to write tests for a type not 100% tested
   // is already estimated properly with the rule "Code should be tested".
   Debt = n.NbLinesOfCodeNotCovered.Linear(1,2, 50,60).ToMinutes().ToDebt(),

   Severity = Severity.High
} 

//<Description>
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// Often covering the few percents of remaining uncovered code of 
// one or several classes in a namespace
// requires as much work as covering the first 90%.
// For this reason, often teams estimate that 90% coverage is enough.
// However *untestable code* usually means *poorly written code* 
// which usually leads to *error prone code*.
// So it might be worth refactoring and making sure to cover the few uncovered lines of code
// **because most tricky bugs might come from this small portion of hard-to-test code**.
//
// Not all classes should be 100% covered by tests (like UI code can be hard to test)
// but you should make sure that most of the logic of your application
// is defined in some *easy-to-test classes*, 100% covered by tests.
//
// Issues of this rule have a **High** severity because as explained,
// such situation is *bug-prone*.
//</Description>

//<HowToFix>
// Write more unit-tests dedicated to cover code not covered yet in the namespace.
// If you find some *hard-to-test code*, it is certainly a sign that this code
// is not *well designed* and hence, needs refactoring.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types that used to be 100% covered by tests should still be 100% covered</Name>
        
warnif count > 0
from t in JustMyCode.Types where 
   t.IsPresentInBothBuilds() &&
   t.OlderVersion().PercentageCoverage == 100 &&
   t.PercentageCoverage < 100

from m in t .MethodsAndContructors where 
  m.NbLinesOfCode> 0 && 
  m.PercentageCoverage < 100 &&
 !m.IsExcludedFromCoverage

select new {
   m, 
   m.PercentageCoverage, 

   // Simplistic Debt estimation, because the effort to write tests for a method not 100% tested
   // is already estimated properly with the rule "Code should be tested".
   Debt = t.NbLinesOfCodeNotCovered.Linear(1,2, 10,10).ToMinutes().ToDebt(),

   Severity = Severity.High
}

//<Description>
// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// Often covering 10% of remaining uncovered code of a class, 
// requires as much work as covering the first 90%.
// For this reason, typically teams estimate that 90% coverage is enough.
// However *untestable code* usually means *poorly written code* 
// which usually leads to *error prone code*.
// So it might be worth refactoring and making sure to cover the 10% remaining code
// **because most tricky bugs might come from this small portion of hard-to-test code**.
//
// Not all classes should be 100% covered by tests (like UI code can be hard to test)
// but you should make sure that most of the logic of your application
// is defined in some *easy-to-test classes*, 100% covered by tests.
//
// In this context, this rule warns when a type fully covered by tests is now only partially covered.
//
// Issues of this rule have a **High** severity because often,
// a type that used to be 100% and is not covered anymore 
// is a bug-prone situation that should be carefully handled.
//</Description>

//<HowToFix>
// Write more unit-tests dedicated to cover code not covered anymore.
// If you find some *hard-to-test code*, it is certainly a sign that this code
// is not *well designed* and hence, needs refactoring.
//
// You'll find code impossible to cover by unit-tests, like calls to *MessageBox.Show()*.
// An infrastructure must be defined to be able to *mock* such code at test-time.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types tagged with FullCoveredAttribute should be 100% covered</Name>
warnif count > 0 
from t in Application.Types where
  t.HasAttribute ("NDepend.Attributes.FullCoveredAttribute".AllowNoMatch()) &&
  t.PercentageCoverage < 100

from m in t .MethodsAndContructors where 
  m.NbLinesOfCode> 0 && 
  m.PercentageCoverage < 100 &&
 !m.IsExcludedFromCoverage

select new { 
   m, 
   m.PercentageCoverage, 
   m.NbLinesOfCodeNotCovered, 
   m.NbLinesOfCode, 

   // Simplistic Debt estimation, because the effort to write tests for a method not 100% tested
   // is already estimated properly with the rule "Code should be tested".
   Debt = m.NbLinesOfCodeNotCovered.Linear(1,2, 10,10).ToMinutes().ToDebt(),

   Severity = Severity.High
}

//<Description>
// This rule lists methods partially covered by tests, of types tagged with
// **FullCoveredAttribute**.
//
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// By using a **FullCoveredAttribute**, you can express in source code the intention
// that a class is 100% covered by tests, and should remain 100% covered in the future.
// If you don't want to link *NDepend.API.dll*, 
// you can use your own attribute and adapt the source code of this rule.
//
// Benefits of using a **FullCoveredAttribute** are twofold:
// Not only the intention is expressed in source code,
// but it is also continuously checked by the present rule.
//
// Often covering 10% of remaining uncovered code of a class, 
// requires as much work as covering the first 90%.
// For this reason, often teams estimate that 90% coverage is enough.
// However *untestable code* usually means *poorly written code* which usually means *error prone code*.
// So it might be worth refactoring and making sure to cover the 10% remaining code
// **because most tricky bugs might come from this small portion of hard-to-test code**.
//
// Not all classes should be 100% covered by tests (like UI code can be hard to test)
// but you should make sure that most of the logic of your application
// is defined in some *easy-to-test classes*, 100% covered by tests.
//
// Issues of this rule have a **High** severity because often,
// a type that used to be 100% and is not covered anymore 
// is a bug-prone situation that should be carefully handled.
//</Description>

//<HowToFix>
// Write more unit-tests dedicated to cover code of matched classes not covered yet.
// If you find some *hard-to-test code*, it is certainly a sign that this code
// is not *well designed* and hence, needs refactoring.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types 100% covered should be tagged with FullCoveredAttribute</Name>
        
warnif count > 0 from t in JustMyCode.Types where
 !t.HasAttribute ("NDepend.Attributes.FullCoveredAttribute".AllowNoMatch()) &&
  t.PercentageCoverage == 100 &&
 !t.IsGeneratedByCompiler
select new { 
   t,
   t.NbLinesOfCode,
   Debt = 3.ToMinutes().ToDebt(), // It is fast to add such attribute to a type.
   Severity = Severity.Low
}

//<Description>
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// By using a **FullCoveredAttribute**, you can express in source code the intention
// that a class is 100% covered by tests, and should remain 100% covered in the future.
//
// Benefits of using a **FullCoveredAttribute** are twofold:
// Not only the intention is expressed in source code,
// but it is also continuously checked by the present rule.
//
// Issues of this rule have an **Low** severity because they don't reflect
// a problem, but provide an advice for potential improvement.
//</Description>

//<HowToFix>
// Just tag types 100% covered by tests with the **FullCoveredAttribute**
// that can be found in *NDepend.API.dll*,
// or by an attribute of yours defined in your own code 
// (in which case this rule must be adapted).
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods should have a low C.R.A.P score</Name>

warnif count > 0
from m in JustMyCode.Methods

// Don't match too short methods
where m.NbLinesOfCode > 10 && m.CoverageDataAvailable

let CC = m.CyclomaticComplexity
let uncov = (100 - m.PercentageCoverage) / 100f
let CRAP = (double)(CC * CC * uncov * uncov * uncov) + CC
where CRAP != null && CRAP > 30
orderby CRAP descending, m.NbLinesOfCode descending
select new { 
   m, 
   CRAP, 
   CC, 
   m.PercentageCoverage, m.NbLinesOfCode,

   // CRAP score equals 30   => 10 minutes debt
   // CRAP score equals 3000 => 3 hours to write tests
   Debt = CRAP.Linear(30,10,  3000, 3*60).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is executed only if some code coverage data is imported
// from some code coverage files.
//
// So far this rule is disabled because other code coverage rules 
// assess properly code coverage issues.
//
// **Change Risk Analyzer and Predictor** (i.e. CRAP) is a code metric
// that helps in pinpointing overly both complex and untested code.
// Is has been first defined here: 
// http://www.artima.com/weblogs/viewpost.jsp?thread=215899
//
// The Formula is:  **CRAP(m) = CC(m)^2 * (1 – cov(m)/100)^3 + CC(m)**
//
// • where *CC(m)* is the *cyclomatic complexity* of the method *m*
//
// • and *cov(m)* is the *percentage coverage* by tests of the method *m*
//
// Matched methods cumulates two highly *error prone* code smells:
//
// • A complex method, difficult to develop and maintain.
//
// • Non 100% covered code, difficult to refactor without introducing any regression bug.
//
// The higher the CRAP score, the more painful to maintain and error prone is the method.
//
// An arbitrary threshold of 30 is fixed for this code rule as suggested by inventors.
//
// Notice that no amount of testing will keep methods with a Cyclomatic Complexity
// higher than 30, out of CRAP territory.
//
// Notice that this rule doesn't match too short method
// with less than 10 lines of code.
//</Description>

//<HowToFix>
// In such situation, it is recommended to both refactor the complex method logic
// into several smaller and less complex methods 
// (that might belong to some new types especially created),
// and also write unit-tests to full cover the refactored logic. 
//
// You'll find code impossible to cover by unit-tests, like calls to *MessageBox.Show()*.
// An infrastructure must be defined to be able to *mock* such code at test-time.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Test Methods</Name>

let testAttr = ThirdParty.Types.WithNameIn("TestAttribute", "TestCaseAttribute")
let testMethods = Methods.TaggedWithAnyAttributes(testAttr)
from m in testMethods 
select m

//<Description>
// We advise to not include test assemblies in code analyzed by NDepend.
// We estimate that it is acceptable and practical to lower the quality gate of test code,
// because the important measures for tests are:
//
// • The coverage ratio, 
//
// • And the amount of logic results asserted: This includes both
// assertions in test code, and assertions in code covered by tests, 
// like *Code Contract* assertions and *Debug.Assert(…)* assertions.
//
// But if you wish to enforce the quality of test code, you'll need to 
// consider test assemblies in your list of application assemblies 
// analyzed by NDepend.
//
// In such situation, this code query lists tests methods and you can 
// reuse this code in custom rules.
//</Description>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods directly called by test Methods</Name>

let testAttr = ThirdParty.Types.WithNameIn("TestAttribute", "TestCaseAttribute")
let testMethods = Methods.TaggedWithAnyAttributes(testAttr).ToHashSet()

// --- Uncomment this line if your test methods are in dedicated test assemblies ---
//let testAssemblies = testMethods.ParentAssemblies().ToHashSet()

from m in Application.Methods.UsedByAny(testMethods)

// --- Uncomment this line if your test methods are in dedicated test assemblies ---
//where !testAssemblies.Contains(m.ParentAssembly)

select new { m , 
             calledByTests = m.MethodsCallingMe.Intersect(testMethods ),
             // --- Uncomment this line if your project import some coverage data ---
             // m.PercentageCoverage 
}


//<Description>
// This query lists all methods directly called by tests methods.
// Overrides of virtual and abstract methods, called through polymorphism, are not listed.
// Methods solely invoked through a delegate are not listed.
// Methods solely invoked through reflection are not listed.
//
// We advise to not include test assemblies in code analyzed by NDepend.
// We estimate that it is acceptable and practical to lower the quality gate of test code,
// because the important measures for tests are:
//
// • The coverage ratio, 
//
// • And the amount of logic results asserted: This includes both
// assertions in test code, and assertions in code covered by tests, 
// like *Code Contract* assertions and *Debug.Assert(…)* assertions.
//
// But if you wish to run this code query,
// you'll need to consider test assemblies in your list of 
// application assemblies analyzed by NDepend.
//</Description>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods directly and indirectly called by test Methods</Name>

let testAttr = from t in ThirdParty.Types.WithNameIn("TestAttribute", "TestCaseAttribute") select t
let testMethods = Methods.TaggedWithAnyAttributes(testAttr)

// --- Uncomment this line if your test methods are in dedicated test assemblies ---
// let testAssemblies = testMethods.ParentAssemblies().ToHashSet()

let depthOfCalledByTest = Application.Methods.DepthOfIsUsedByAny(testMethods)
from pair in depthOfCalledByTest
where pair.Value > 0 
orderby pair.Value ascending
// --- Uncomment this line if your test methods are in dedicated test assemblies ---
//&& !testAssemblies.Contains(pair.CodeElement.ParentAssembly)

select new { 
  method = pair.CodeElement, 
  // (depthOfCalledByTests == 1) means that the method is directly called by tests
  // (depthOfCalledByTests == 2) means that the method is directly called by a method directly called by tests
  // …
  depthOfCalledByTests = pair.Value,
  nbLinesOfCode = pair.CodeElement.NbLinesOfCode,
  // --- Uncomment this line if your project import some coverage data ---
  // m.PercentageCoverage
}

//<Description>
// This query lists all methods *directly or indirectly* called by tests methods.
// *Indirectly* called by a test means that a test method calls a method, that calls a method…
// From this recursion, a code metric named *depthOfCalledByTests* is inferred,
// The value *1* means directly called by test,
// the value *2* means called by a method that is called by a test…
//
// Overrides of virtual and abstract methods, called through polymorphism, are not listed.
// Methods solely invoked through a delegate are not listed.
// Methods solely invoked through reflection are not listed.
//
// We advise to not include test assemblies in code analyzed by NDepend.
// We estimate that it is acceptable and practical to lower the quality gate of test code,
// because the important measures for tests are:
//
// • The coverage ratio, 
//
// • And the amount of logic results asserted: This includes both
// assertions in test code, and assertions in code covered by tests, 
// like *Code Contract* assertions and *Debug.Assert(…)* assertions.
//
// But if you wish to run this code query,
// you'll need to consider test assemblies in your list of 
// application assemblies analyzed by NDepend.
//</Description>]]></Query>
    </Group>
    <Group Name="Dead Code" Active="True" ShownInReport="True">
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Potentially Dead Types</Name>
        
warnif count > 0
// Filter procedure for types that should'nt be considered as dead
let canTypeBeConsideredAsDeadProc = new Func<IType, bool>(
   t => !t.IsPublic && //   Public types might be used by client applications of your assemblies.
         t.Name != "Program" && 
        !t.IsGeneratedByCompiler &&

         // If you don't want to link NDepend.API.dll, you can use your own IsNotDeadCodeAttribute 
         // and adapt the source code of this rule.
        !t.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&

         // Exclude static types that define only const fields
         // because they cannot be seen as used in IL code.
        !(t.IsStatic && t.NbMethods == 0 && !t.Fields.Where(f => !f.IsLiteral).Any()))

// Select types unused
let typesUnused = 
   from t in JustMyCode.Types where
   t.NbTypesUsingMe == 0 && canTypeBeConsideredAsDeadProc(t)
   select t

// Dead types = types used only by unused types (recursive)
let deadTypesMetric = typesUnused.FillIterative(
types => from t in codeBase.Application.Types.UsedByAny(types).Except(types)
         where canTypeBeConsideredAsDeadProc(t) &&
               t.TypesUsingMe.Intersect(types).Count() == t.NbTypesUsingMe
         select t)

from t in deadTypesMetric.DefinitionDomain
select new { 
   t, 
   depth = deadTypesMetric[t],
   t.TypesUsingMe, 
   Debt = 15.ToMinutes().ToDebt(),
   AnnualInterest = (10 + (t.NbLinesOfCode ?? 1)).ToMinutes().ToAnnualInterest()
}

//<Description>
// This rule lists *potentially* **dead types**.
// A dead type is a type that can be removed
// because it is never used by the program.
//
// This rule lists not only types not used anywhere in code,
// but also types used only by types not used anywhere in code.
// This is why this rule comes with a column *TypesusingMe* and
// this is why there is a code metric named *depth*:
//
// • A *depth* value of *0* means the type is not used.
//
// • A *depth* value of *1* means the type is used only by types not used.
//
// • etc…
//
// By reading the source code of this rule, you'll see that by default,
// *public* types are not matched, because such type might not be used
// by the analyzed code, but still be used by client code, not analyzed by NDepend.
// This default behavior can be easily changed.
//</Description>

//<HowToFix>
// *Static analysis* cannot provide an *exact* list of dead types,
// because there are several ways to use a type *dynamically* (like through reflection).
//
// For each type matched by this query, first investigate if the type is used somehow
// (like through reflection).
// If the type is really never used, it is important to remove it 
// to avoid maintaining useless code.
// If you estimate the code of the type might be used in the future, 
// at least comment it, and provide an explanatory comment about the future intentions.
//
// If a type is used somehow,
// but still is matched by this rule, you can tag it with the attribute 
// **IsNotDeadCodeAttribute** found in *NDepend.API.dll* to avoid matching the type again.
// You can also provide your own attribute for this need, 
// but then you'll need to adapt this code rule.
//
// Issues of this rule have a **Debt** equal to 15 minutes because it only
// takes a short while to investigate if a type can be safely discarded.
// The **Annual Interest** of issues of this rule, the annual cost to not
// fix such issue, is proportional to the type #lines of code, because
// the bigger the type is, the more it slows down maintenance.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Potentially Dead Methods</Name>
        
warnif count > 0
// Filter procedure for methods that should'nt be considered as dead
let canMethodBeConsideredAsDeadProc = new Func<IMethod, bool>(
    m => !m.IsPubliclyVisible &&       // Public methods might be used by client applications of your assemblies.
         !m.IsEntryPoint &&            // Main() method is not used by-design.
         !m.IsExplicitInterfaceImpl && // The IL code never explicitly calls explicit interface methods implementation.
         !m.IsClassConstructor &&      // The IL code never explicitly calls class constructors.
         !m.IsFinalizer &&             // The IL code never explicitly calls finalizers.
         !m.IsVirtual &&               // Only check for non virtual method that are not seen as used in IL.
         !(m.IsConstructor &&          // Don't take account of protected ctor that might be call by a derived ctors.
           m.IsProtected) &&
         !m.IsEventAdder &&            // The IL code never explicitly calls events adder/remover.
         !m.IsEventRemover &&
         !m.IsGeneratedByCompiler &&
         !m.ParentType.IsDelegate &&

         // Methods tagged with these two attributes are called by the serialization infrastructure.
         !m.HasAttribute("System.Runtime.Serialization.OnSerializingAttribute".AllowNoMatch()) &&
         !m.HasAttribute("System.Runtime.Serialization.OnDeserializedAttribute".AllowNoMatch()) &&

         // If you don't want to link NDepend.API.dll, you can use your own IsNotDeadCodeAttribute 
         // and adapt the source code of this rule.
         !m.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()))

// Get methods unused
let methodsUnused = 
   from m in JustMyCode.Methods where 
   m.NbMethodsCallingMe == 0 && 
   canMethodBeConsideredAsDeadProc(m)
   select m

// Dead methods = methods used only by unused methods (recursive)
let deadMethodsMetric = methodsUnused.FillIterative(
   methods => // Unique loop, just to let a chance to build the hashset.
              from o in (new object()).ToEnumerable()
              // Use a hashet to make Intersect calls much faster!
              let hashset = methods.ToHashSet()
              from m in codeBase.Application.Methods.UsedByAny(methods).Except(methods)
              where canMethodBeConsideredAsDeadProc(m) &&
                    // Select methods called only by methods already considered as dead
                    hashset.Intersect(m.MethodsCallingMe).Count() == m.NbMethodsCallingMe
              select m)

from m in JustMyCode.Methods.Intersect(deadMethodsMetric.DefinitionDomain)
let depth = deadMethodsMetric[m]
select new { 
   m,
   depth,
   m.MethodsCallingMe,    
   Debt = (10 + 3*depth).ToMinutes().ToDebt(),
   AnnualInterest = (8 + (m.NbLinesOfCode ?? 1)).ToMinutes().ToAnnualInterest()
}
      
//<Description>
// This rule lists *potentially* **dead methods**.
// A dead method is a method that can be removed
// because it is never called by the program.
//
// This rule lists not only methods not called anywhere in code,
// but also methods called only by methods not called anywhere in code.
// This is why this rule comes with a column *MethodsCallingMe* and
// this is why there is a code metric named *depth*:
//
// • A *depth* value of *0* means the method is not called.
//
// • A *depth* value of *1* means the method is called only by methods not called.
//
// • etc…
//
// By reading the source code of this rule, you'll see that by default,
// *public* methods are not matched, because such method might not be called
// by the analyzed code, but still be called by client code, not analyzed by NDepend.
// This default behavior can be easily changed.
//</Description>

//<HowToFix>
// *Static analysis* cannot provide an *exact* list of dead methods,
// because there are several ways to invoke a method *dynamically* (like through reflection).
//
// For each method matched by this query, first investigate if the method is invoked somehow
// (like through reflection).
// If the method is really never invoked, it is important to remove it 
// to avoid maintaining useless code.
// If you estimate the code of the method might be used in the future, 
// at least comment it, and provide an explanatory comment about the future intentions.
//
// If a method is invoked somehow,
// but still is matched by this rule, you can tag it with the attribute 
// **IsNotDeadCodeAttribute** found in *NDepend.API.dll* to avoid matching the method again.
// You can also provide your own attribute for this need, 
// but then you'll need to adapt this code rule.
//
// Issues of this rule have a **Debt** equal to 10 minutes because it only
// takes a short while to investigate if a method can be safely discarded.
// On top of these 10 minutes, the depth of usage of such method adds up
// 3 minutes per unity because dead method only called by dead code 
// takes a bit more time to be investigated.
//
// The **Annual Interest** of issues of this rule, the annual cost to not
// fix such issue, is proportional to the type #lines of code, because
// the bigger the method is, the more it slows down maintenance.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Potentially Dead Fields</Name>
warnif count > 0
from f in JustMyCode.Fields where
   f.NbMethodsUsingMe == 0 && 
   !f.IsPublic &&     // Although not recommended, public fields might be used by client applications of your assemblies.
   !f.IsLiteral &&    // The IL code never explicitly uses literal fields.
   !f.IsEnumValue &&  // The IL code never explicitly uses enumeration value.
    f.Name != "value__"  && // Field named 'value__' are relative to enumerations and the IL code never explicitly uses them.
   !f.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
   !f.IsGeneratedByCompiler &&
   !f.ParentType.Name.StartsWith("Jvm")
   // If you don't want to link NDepend.API.dll, you can use your own IsNotDeadCodeAttribute
   // and adapt the source code of this rule.
select new {
   f, 
   Debt = 10.ToMinutes().ToDebt(),
   AnnualInterest = 8.ToMinutes().ToAnnualInterest()
}

//<Description>
// This rule lists *potentially* **dead fields**.
// A dead field is a field that can be removed
// because it is never used by the program.
//
// By reading the source code of this rule, you'll see that by default,
// *public* fields are not matched, because such field might not be used
// by the analyzed code, but still be used by client code, not analyzed by NDepend.
// This default behavior can be easily changed.
// Some others default rules in the *Visibility* group, warn about public fields. 
//
// More restrictions are applied by this rule because of some *by-design* limitations.
// NDepend mostly analyzes compiled IL code, and the information that
// an enumeration value or a literal constant (which are fields) is used
// is lost in IL code. Hence by default this rule won't match such field.
//</Description>

//<HowToFix>
// *Static analysis* cannot provide an *exact* list of dead fields,
// because there are several ways to assign or read a field *dynamically* 
// (like through reflection).
//
// For each field matched by this query, first investigate 
// if the field is used somehow (like through reflection).
// If the field is really never used, it is important to remove it 
// to avoid maintaining a useless code element.
//
// If a field is used somehow,
// but still is matched by this rule, you can tag it with the attribute 
// **IsNotDeadCodeAttribute** found in *NDepend.API.dll* 
// to avoid matching the field again.
// You can also provide your own attribute for this need, 
// but then you'll need to adapt this code rule.
//
// Issues of this rule have a **Debt** equal to 10 minutes because it only
// takes a short while to investigate if a method can be safely discarded.
// The **Annual Interest** of issues of this rule, the annual cost to not
// fix such issue, is set by default to 8 minutes per unused field matched.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Wrong usage of IsNotDeadCodeAttribute</Name>
warnif count > 0

let tAttr = Types.WithFullName("NDepend.Attributes.IsNotDeadCodeAttribute").FirstOrDefault()
where tAttr != null

// Get types that do a wrong usage of IsNotDeadCodeAttribute
let types = from t in Application.Types where 
   t.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&

   ( // types used don't need to be tagged with IsNotDeadCodeAttribute!
     t.TypesUsingMe.Count(t1 => 
        !t.NestedTypes.Contains(t1) && 
        !t1.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) ) > 0  ||
   
     // Static types that define only const fields cannot be seen as used in IL code.
     // They don't need to be tagged with IsNotDeadCodeAttribute.
     (t.IsStatic && t.NbMethods == 0 && !t.Fields.Where(f => !f.IsLiteral).Any())
   )
   select t

// Get methods that do a wrong usage of IsNotDeadCodeAttribute
let methods = from m in Application.Methods where 
   m.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
   m.MethodsCallingMe.Count(m1 => !m1.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch())) > 0
   select m

// Get fields that do a wrong usage of IsNotDeadCodeAttribute
let fields = from f in Application.Fields where 
   f.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
   f.MethodsUsingMe.Count(m1 => !m1.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch())) > 0
   select f

from member in types.Cast<IMember>().Concat(methods).Concat(fields)
select new { 
   member,
   Debt = 4.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// The attribute **NDepend.Attributes.IsNotDeadCodeAttribute**
// is defined in *NDepend.API.dll*. This attribute is used
// to mean that a code element is not used directly, but is used 
// somehow, like through reflection.
//
// This attribute is used in the dead code rules,
// *Potentially dead Types*, *Potentially dead Methods* 
// and *Potentially dead Fields*. 
// If you don't want to link *NDepend.API.dll*, you can use 
// your own *IsNotDeadCodeAttribute* and adapt the source code of
// this rule, and the source code of the *dead code* rules.
//
// In this context, this code rule matches code elements 
// (types, methods, fields) that are tagged with this attribute,
// but still used directly somewhere in the code.
//</Description>

//<HowToFix>
// Just remove *IsNotDeadCodeAttribute* tagging of
// types, methods and fields matched by this rule
// because this tag is not useful anymore.
//</HowToFix>]]></Query>
    </Group>
    <Group Name="Visibility" Active="True" ShownInReport="False">
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods that could have a lower visibility</Name>
warnif count > 0 from m in JustMyCode.Methods where 
   m.Visibility != m.OptimalVisibility &&

  !m.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
  !m.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
  // If you don't want to link NDepend.API.dll, you can use your own attributes 
  // and adapt the source code of this rule.
  
  // methods of serialized type must remain public.
  !m.ParentType.HasAttribute("System.Runtime.Serialization.DataContractAttribute".AllowNoMatch()) &&
  !m.ParentType.HasAttribute("System.Xml.Serialization.XmlRootAttribute".AllowNoMatch()) &&
  
  // Eliminate public methods visible outside of their assembly
  // because the rule cannot know if the developer left the method public 
  // intentionally or not.
  !m.IsPubliclyVisible && 

  // Eliminate default constructor from the result.
  // Whatever the visibility of the declaring class,
  // default constructors are public and introduce noise
  // in the current rule.
  !( m.IsConstructor && m.IsPublic && m.NbParameters == 0) &&

  // Don't decrease the visibility of Main() methods.
  !m.IsEntryPoint

select new { 
   m, 
   m.Visibility , 
   CouldBeDeclared = m.OptimalVisibility,
   m.MethodsCallingMe,

   Debt = 30.ToSeconds().ToDebt(), // It is fast to change the method visibility
   Severity = Severity.Medium
}

//<Description>
// This rule warns about methods that can be declared with a lower visibility
// without provoking any compilation error.
// For example *private* is a visibility lower than *internal* 
// which is lower than *public*.
//
// **Narrowing visibility** is a good practice because doing so **promotes encapsulation**.
// The scope from which methods can be called is then reduced to a minimum. 
//
// By default, this rule doesn't match publicly visible methods that could have a 
// lower visibility because it cannot know if the developer left the method public 
// intentionally or not. Public methods matched are declared in non-public types.
//
// Notice that methods tagged with one of the attribute
// *NDepend.Attributes.CannotDecreaseVisibilityAttribute* or
// *NDepend.Attributes.IsNotDeadCodeAttribute*, found in *NDepend.API.dll*
// are not matched. If you don't want to link *NDepend.API.dll* but still
// wish to rely on this facility, you can declare these attributes in your code.
//</Description>

//<HowToFix>
// Declare each matched method with the specified *optimal visibility*
// in the *CouldBeDeclared* rule result column.
//
// By default, this rule matches *public methods*. If you are publishing an API
// many public methods matched should remain public. In such situation,
// you can opt for the *coarse solution* to this problem by adding in the 
// rule source code *&& !m.IsPubliclyVisible* or you can prefer the 
// *finer solution* by tagging each concerned method with 
// *CannotDecreaseVisibilityAttribute*.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types that could have a lower visibility</Name>
warnif count > 0 from t in JustMyCode.Types where 

  t.Visibility != t.OptimalVisibility &&

  // If you don't want to link NDepend.API.dll, you can use your own attributes
  // and adapt the source code of this rule.
  !t.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
  !t.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&

  // XML serialized type must remain public.
  !t.HasAttribute("System.Xml.Serialization.XmlRootAttribute".AllowNoMatch()) &&

  // Eliminate public types visible outside of their assembly
  // because the rule cannot know if the developer left the type public 
  // intentionally or not.
  !t.IsPubliclyVisible && 

  // Static types that define only const fields cannot be seen as used in IL code.
  // They don't have to be tagged with CannotDecreaseVisibilityAttribute.
  !( t.IsStatic && 
    !t.Methods.Any(m => !m.IsClassConstructor) && 
    !t.Fields.Any(f => !f.IsLiteral && !(f.IsStatic && f.IsInitOnly))) &&

  // A type used by an interface that has the same visibility
  // cannot have its visibility decreased, else a compilation error occurs!
  !t.TypesUsingMe.Any(tUser => 
        tUser.IsInterface && 
        tUser.Visibility == t.Visibility) &&

  // Don't change the visibility of a type that contain an entry point method.
  !t.Methods.Any(m =>m.IsEntryPoint)

select new { 
   t, 
   t.Visibility , 
   CouldBeDeclared = t.OptimalVisibility, 
   t.TypesUsingMe,

   Debt = 30.ToSeconds().ToDebt(), // It is fast to change the method visibility
   Severity = Severity.Medium
}

//<Description>
// This rule warns about types that can be declared with a lower visibility
// without provoking any compilation error.
// For example *private* is a visibility lower than *internal* 
// which is lower than *public*.
//
// **Narrowing visibility** is a good practice because doing so **promotes encapsulation**.
// The scope from which types can be consumed is then reduced to a minimum. 
//
// By default, this rule doesn't match publicly visible types that could have 
// a lower visibility because it cannot know if the developer left the type public 
// intentionally or not. Public types matched are nested in non-public types.
//
// Notice that types tagged with one of the attribute
// *NDepend.Attributes.CannotDecreaseVisibilityAttribute* or
// *NDepend.Attributes.IsNotDeadCodeAttribute*, found in *NDepend.API.dll*
// are not matched. If you don't want to link *NDepend.API.dll* but still
// wish to rely on this facility, you can declare these attributes in your code.
//</Description>

//<HowToFix>
// Declare each matched type with the specified *optimal visibility*
// in the *CouldBeDeclared* rule result column.
//
// By default, this rule matches *public types*. If you are publishing an API
// many public types matched should remain public. In such situation,
// you can opt for the *coarse solution* to this problem by adding in the 
// rule source code *&& !m.IsPubliclyVisible* or you can prefer the 
// *finer solution* by tagging each concerned type with 
// *CannotDecreaseVisibilityAttribute*.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Fields that could have a lower visibility</Name>
warnif count > 0 from f in JustMyCode.Fields where 
  f.Visibility != f.OptimalVisibility &&
 !f.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
 !f.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
  // If you don't want to link NDepend.API.dll, you can use your own attributes
  // and adapt the source code of this rule.
  
  // XML serialized fields must remain public.
 !f.HasAttribute("System.Xml.Serialization.XmlElementAttribute".AllowNoMatch()) && 
 !f.HasAttribute("System.Xml.Serialization.XmlAttributeAttribute".AllowNoMatch()) &&
 !f.HasAttribute("System.Xml.Serialization.XmlArrayAttribute".AllowNoMatch()) &&
 !f.HasAttribute("System.Xml.Serialization.XmlArrayItemAttribute".AllowNoMatch()) &&
 
  // Don't check for serialized fields visibility
 !f.HasAttribute("System.Runtime.Serialization.DataMemberAttribute".AllowNoMatch()) &&
 
  // Eliminate public fields visible outside of their assembly
  // because the rule cannot know if the developer left the field public 
  // intentionally or not.
 !f.IsPubliclyVisible 

select new { 
   f, 
   f.Visibility , 
   CouldBeDeclared = f.OptimalVisibility,
   f.MethodsUsingMe,

   Debt = 30.ToSeconds().ToDebt(), // It is fast to change the field visibility
   Severity = Severity.Medium
}

//<Description>
// This rule warns about fields that can be declared with a lower visibility
// without provoking any compilation error.
// For example *private* is a visibility lower than *internal* 
// which is lower than *public*.
//
// **Narrowing visibility** is a good practice because doing so **promotes encapsulation**.
// The scope from which fields can be consumed is then reduced to a minimum. 
//
// By default, this rule doesn't match publicly visible fields that could have a 
// lower visibility because it cannot know if the developer left the field public 
// intentionally or not. Public fields matched are declared in non-public types.
//
// Notice that fields tagged with one of the attribute
// *NDepend.Attributes.CannotDecreaseVisibilityAttribute* or
// *NDepend.Attributes.IsNotDeadCodeAttribute*, found in *NDepend.API.dll*
// are not matched. If you don't want to link *NDepend.API.dll* but still
// wish to rely on this facility, you can declare these attributes in your code.
//</Description>

//<HowToFix>
// Declare each matched field with the specified *optimal visibility*
// in the *CouldBeDeclared* rule result column.
//
// By default, this rule matches *public fields*. If you are publishing an API
// some public fields matched should remain public. In such situation,
// you can opt for the *coarse solution* to this problem by adding in the 
// rule source code *&& !m.IsPubliclyVisible* or you can prefer the 
// *finer solution* by tagging eah concerned field with 
// *CannotDecreaseVisibilityAttribute*.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types that could be declared as private, nested in a parent type</Name>

warnif count > 0 
from t in JustMyCode.Types
where !t.IsGeneratedByCompiler &&
      !t.IsNested &&
      !t.IsPubliclyVisible &&
      !t.IsEnumeration &&
       // Only one type user…
       t.TypesUsingMe.Count() == 1 
let couldBeNestedIn = t.TypesUsingMe.Single()
where !couldBeNestedIn.IsGeneratedByCompiler &&
       // …declared in the same namespace
       couldBeNestedIn.ParentNamespace == t.ParentNamespace
select new { 
   t, 
   couldBeNestedIn,
   Debt = 3.ToMinutes().ToDebt(), // It is fast to nest a type into another one
   Severity = Severity.Low       // This rule proposes advices, not potential problems
}

//<Description>
// This rule matches types that can be potentially 
// *nested* and declared *private* into another type.
//
// The conditions for a type to be potentially nested 
// into a *parent type* are:
//
// • the *parent type* is the only type consuming it,
//
// • the type and the *parent type* are declared in the same namespace.
//
// Declaring a type as private into a parent type **promotes encapsulation**.
// The scope from which the type can be consumed is then reduced to a minimum.
//</Description>

//<HowToFix>
// Nest each matched *type* into the specified *parent type* and
// declare it as private.
//
// However *nested private types* are hardly testable. Hence this rule  
// might not be applied to types consumed directly by tests.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid publicly visible constant fields</Name>
warnif count > 0 
from f in JustMyCode.Fields
where f.IsLiteral && 
      f.IsPubliclyVisible && 
     !f.IsEnumValue
select new {
   f,

   Debt = 30.ToSeconds().ToDebt(), // It is fast to update field declaration
   Severity = Severity.Medium
}

//<Description>
// This rule warns about constant fields that are visible outside their 
// parent assembly. Such field, when used from outside its parent assembly,
// has its constant value *hard-coded* into the client assembly.
// Hence, when changing the field's value, it is *mandatory* to recompile 
// all assemblies that consume the field, else the program will run
// with different constant values in-memory. Certainly in such situation
// bugs are lurking.
//</Description>

//<HowToFix>
// Declare matched fields as **static readonly** instead of **constant**. 
// This way, the field value is *safely changeable* without the need to 
// recompile client assemblies.
//
// Notice that enumeration value fields suffer from the same *potential
// pitfall*. But enumeration values cannot be declared as 
// *static readonly* hence the rule comes with the condition
// **&& !f.IsEnumValue** to avoid matching these. Unless you decide
// to banish public enumerations, just let the rule *as is*.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Fields should be declared as private</Name>
warnif count > 0 from f in JustMyCode.Fields where 
 !f.IsPrivate && 

 // These conditions filter cases where fields 
 // doesn't represent state that should be encapsulated. 
 !f.IsGeneratedByCompiler && 
 !f.IsSpecialName && 
 !f.IsInitOnly && 
 !f.IsLiteral && 
 !f.IsEnumValue &&
 !f.HasAttribute("System.Xml.Serialization.XmlAttributeAttribute".AllowNoMatch()) &&
 !f.HasAttribute("System.Runtime.Serialization.DataMemberAttribute".AllowNoMatch())

// A non-private field assigned from outside its class,
// usually leads to complicated field state management.
let outsideMethodsAssigningMe = 
   f.MethodsAssigningMe.Where(m => m.ParentType != f.ParentType)

select new { 
   f, 
   f.Visibility, 
   outsideMethodsAssigningMe,
   
   Debt = (60+20*outsideMethodsAssigningMe.Count()).ToSeconds().ToDebt(),
   // The cost to leave such issue unfixed is higher if the field is publicly visible!
   AnnualInterest = Severity.Medium.AnnualInterestThreshold() * (f.IsPubliclyVisible ? 3 : 1)
}

//<Description>
// This rule matches **non-private and mutable fields**.
// *Mutable* means that the field value can be modified.
// Typically mutable fields are *non-constant*, 
// *non-readonly* fields.
//
// Fields should be considered as **implementation details**
// and as a consequence they should be declared as private.
//
// If something goes wrong with a *non-private field*, 
// the culprit can be anywhere, and so in order to track down 
// the bug, you may have to look at quite a lot of code.
//
// A private field, by contrast, can only be assigned from 
// inside the same class, so if something goes wrong with that, 
// there is usually only one source file to look at.
//
// Issues of this rule are fast to get fixed, and they have
// a debt proportional to the number of methods assigning 
// the field.
//</Description>

//<HowToFix>
// Declare a matched mutable field as *private*, or declare it 
// as *readonly*. 
//
// If code outside the type needs to access the field
// you can encapsulate the field accesses in a read-write property.
// At least with a read-write property you can set a debug breakpoint
// on the property setter, which makes easier to track write-accesses 
// in case of problem.
//</HowToFix>
]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[//<Name>Constructors of abstract classes should be declared as protected or private</Name>
warnif count > 0
from t in Application.Types where 
  t.IsClass && 
  t.IsAbstract
let ctors = t.Constructors.Where(c => !c.IsProtected && !c.IsPrivate)
where ctors.Count() > 0
select new {
   t, 
   ctors,

   Debt = 30.ToSeconds().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Constructors of abstract classes can only be called from derived 
// classes.
// 
// Because a public constructor is creating instances of its class, 
// and it is forbidden to create instances of an *abstract* type, 
// as a consequence an abstract class with a public constructor is 
// wrong design.
//</Description>

//<HowToFix>
// To fix a violation of this rule, 
// either declare the constructor as *protected*, 
// or do not declare the type as *abstract*.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[//<Name>Avoid public methods not publicly visible</Name>

warnif count > 0
from m in JustMyCode.Methods where 
   !m.IsPubliclyVisible && m.IsPublic &&

   // Eliminate virtual methods
   !m.IsVirtual &&
   // Eliminate interface and delegate types
   !m.ParentType.IsInterface &&
   !m.ParentType.IsDelegate &&
   // Eliminate default constructors
   !(m.IsConstructor && m.NbParameters == 0) &&
   // Eliminate operators that must be declared public
   !m.IsOperator &&
   // Eliminate methods generated by compiler
   !m.IsGeneratedByCompiler 

let calledOutsideParentType = 
    m.MethodsCallingMe.FirstOrDefault(mCaller => mCaller.ParentType != m.ParentType) != null

select new { 
   m, 
   parentTypeVisibility = m.ParentType.Visibility,
   declareMethodAs = (Visibility) (calledOutsideParentType ? Visibility.Internal : Visibility.Private),
   methodsCaller = m.MethodsCallingMe,

   Debt = 30.ToSeconds().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// This rule warns about methods declared as *public*
// whose parent type is not declared as *public*.
//
// In such situation *public* means, *can be accessed
// from anywhere my parent type is visible*. Some 
// developers think this is an elegant language construct, 
// some others find it misleading.
//
// This rule can be deactivated if you don't agree with it.
// Read the whole debate here:
// http://ericlippert.com/2014/09/15/internal-or-public/
//
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</Description>

//<HowToFix>
// Declare the method as *internal* if it is used outside of 
// its type, else declare it as *private*.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Event handler methods should be declared private</Name>
warnif count > 0
from m in Application.Methods where 
  !m.IsPrivate &&
  !m.IsGeneratedByCompiler &&

   // A method is considered as an event handler if…
   m.NbParameters == 2 &&          // … it has two parameters …
   m.Name.Contains("Object") &&    // … of types Object …
   m.Name.Contains("EventArgs") && // … and EventArgs
   
   // Discard special cases
  !m.ParentType.IsDelegate &&
  !m.IsGeneratedByCompiler

select new { 
   m,
   m.Visibility,
   Debt = 2.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Think of a event handler like for example *OnClickButton()*.
// Typically such method must be declared as private
// and shouldn't be invoked in other context than event firing.
//</Description>

//<HowToFix>
// If you have the need that event handler method should be called
// from another class, then find a code structure that more 
// closely matches the concept of what you're trying to do. 
// Certainly you don't want the other class to click a button; you 
// want the other class to do something that clicking a button  
// also do.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Wrong usage of CannotDecreaseVisibilityAttribute</Name>
warnif count > 0

let tAttr = Types.WithFullName("NDepend.Attributes.CannotDecreaseVisibilityAttribute").FirstOrDefault()
where tAttr != null

// Get types that do a wrong usage of CannotDecreaseVisibilityAttribute
let types = from t in Application.Types where 
   t.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
   ( t.Visibility == t.OptimalVisibility ||

     // Static types that define only const fields cannot be seen as used in IL code.
     // They don't need to be tagged with CannotDecreaseVisibilityAttribute.
     (t.IsStatic && t.NbMethods == 0 && !t.Fields.Any(f => !f.IsLiteral))
   )
   select t

// Get methods that do a wrong usage of CannotDecreaseVisibilityAttribute
let methods = from m in Application.Methods where 
   m.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
   m.Visibility == m.OptimalVisibility
   select m

// Get fields that do a wrong usage of CannotDecreaseVisibilityAttribute
let fields = from f in Application.Fields where 
   f.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
   f.Visibility == f.OptimalVisibility
   select f

from member in types.Cast<IMember>().Concat(methods).Concat(fields)
select new {
   member,
   Debt = 30.ToSeconds().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// The attribute **NDepend.Attributes.CannotDecreaseVisibilityAttribute**
// is defined in *NDepend.API.dll*. If you don't want to reference
// *NDepend.API.dll* you can declare it in your code.
//
// Usage of this attribute means that a code element visibility is not 
// optimal (it can be lowered like for example from *public* to *internal*) 
// but shouldn’t be modified anyway. Typical reasons to do so include:
//
// • Public code elements consumed through reflection, through a mocking
// framework, through XML or binary serialization, through designer, 
// COM interfaces…
//
// • Non-private code element invoked by test code, that would be difficult
// to reach from test if it was declared as *private*.
//
// In such situation *CannotDecreaseVisibilityAttribute* is used to avoid
// that default rules about not-optimal visibility warn. Using this 
// attribute can be seen as an extra burden, but it can also be seen as 
// an opportunity to express in code: **Don't change the visibility else
// something will be broken** 
//
// In this context, this code rule matches code elements 
// (types, methods, fields) that are tagged with this attribute,
// but still already have an optimal visibility.
//</Description>

//<HowToFix>
// Just remove *CannotDecreaseVisibilityAttribute* tagging of
// types, methods and fields matched by this rule
// because this tag is not useful anymore.
//
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods that should be declared as 'public' in C#, 'Public' in VB.NET</Name>
from m in Application.Methods where 
  m.ShouldBePublic
let usedInAssemblies = m.MethodsCallingMe.ParentAssemblies().Except(m.ParentAssembly)
select new {
   m, 
   m.ParentAssembly,
   usedInAssemblies,
   m.MethodsCallingMe
}

//<Description>
// This code query lists methods that *should* be declared
// as *public*. Such method is actually declared as *internal*
// and is consumed from outside its parent assembly
// thanks to the attribute 
// *System.Runtime.CompilerServices.InternalsVisibleToAttribute*.
//
// This query relies on the property
// *NDepend.CodeModel.IMember.ShouldBePublic*
// http://www.ndepend.com/api/webframe.html?NDepend.API~NDepend.CodeModel.IMember~ShouldBePublic.html 
//
// This is just a code query, it is not intended to advise
// you to declare the method as *public*, but to inform you
// that the code actually relies on the peculiar behavior
// of the attribute *InternalsVisibleToAttribute*.
//</Description>]]></Query>
    </Group>
    <Group Name="Immutability" Active="True" ShownInReport="False">
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Fields should be marked as ReadOnly when possible</Name>
warnif count > 0 
from f in JustMyCode.Fields where 
   f.IsImmutable && 
  !f.IsInitOnly && // The condition IsInitOnly matches fields that 
                   // are marked with the C# readonly keyword 
                   // (ReadOnly in VB.NET).
  !f.IsGeneratedByCompiler &&
  !f.IsEventDelegateObject &&

   // Don't warn if a method using the field is also calling a method that has 'ref' and 'out' parameters.
   // This could lead to false positive. A field used in a 'ref' or 'out' parameter cannot be set as read-only.
   f.MethodsUsingMe.SelectMany(m => m.MethodsCalled).FirstOrDefault(m => m.Name.Contains("&")) == null 
   
select new {
   f, 
   f.MethodsReadingMeButNotAssigningMe,
   f.MethodsAssigningMe,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Description>
// This rule warns about instance and static fields that
// can be declared as **readonly**.
//
// This source code of this rule is based on the conditon 
// *IField.IsImmutable*.
// http://www.ndepend.com/api/webframe.html?NDepend.API~NDepend.CodeModel.IField~IsImmutable.html
//
// A field that matches the condition *IsImmutable* 
// is a field that is assigned only by constructors 
// of its class.
//
// For an *instance field*, this means its value 
// will remain constant through the lifetime 
// of the object.
//
// For a *static field*, this means its value will 
// remain constant through the lifetime of the 
// program.
//</Description>

//<HowToFix>
// Declare the  field with the C# *readonly* keyword 
// (*ReadOnly* in VB.NET). This way the intention
// that the field value shouldn't change is made
// explicit.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid non-readonly static fields</Name>
warnif count > 0
from f in Application.Fields
where f.IsStatic && 
     !f.IsEnumValue && 
     !f.IsGeneratedByCompiler &&
     !f.IsLiteral &&
     !f.IsInitOnly

let methodAssigningField = f.MethodsAssigningMe

select new { 
   f, 
   methodAssigningField,
   Debt = (2+8*methodAssigningField.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns about static fields that are not 
// declared as read-only.
//
// In *Object-Oriented-Programming* the natural artifact 
// to hold states that can be modified is **instance fields**.
// Such mutable static fields create *confusion* about
// the expected state at runtime and impairs the code
// testability since the same mutable state is re-used for
// each test.
//
// More discussion on the topic can be found here:
// http://codebetter.com/patricksmacchia/2011/05/04/back-to-basics-usage-of-static-members/
//</Description>

//<HowToFix>
// If the *static* field is just assigned once in the program
// lifetime, make sure to declare it as *readonly* and assign 
// it inline, or from the static constructor.
//
// Else if methods other than the static constructor need to 
// assign the state hold by the static field, refactoring must 
// occur to ensure that this  state is hold through an instance 
// field.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid static fields with a mutable field type</Name>
warnif count > 0
from f in Application.Fields
where f.IsStatic && 
     !f.IsEnumValue && 
     !f.IsGeneratedByCompiler &&
     !f.IsLiteral

let fieldType = f.FieldType
where fieldType != null && 
     !fieldType.IsThirdParty && 
     !fieldType.IsInterface && 
     !fieldType.IsImmutable

select new { 
   f, 
   mutableFieldType = fieldType , 
   isFieldImmutable = f.IsImmutable ? "Immutable" : "Mutable", 
   isFieldReadOnly = f.IsInitOnly ? "ReadOnly" : "Not ReadOnly",
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule warns about static fields whose field type
// is mutable. In such case the static field is 
// holding a state that can be modified.
//
// In *Object-Oriented-Programming* the natural artifact 
// to hold states that can be modified is **instance fields**.
// Hence such static fields create *confusion* about
// the expected state at runtime.
//
// More discussion on the topic can be found here:
// http://codebetter.com/patricksmacchia/2011/05/04/back-to-basics-usage-of-static-members/
//</Description>

//<HowToFix>
// To fix violations of this rule, make sure to
// hold mutable states through objects that are passed
// **explicitly** everywhere they need to be consumed, in 
// opposition to mutable object hold by a static field that 
// makes it modifiable from a bit everywhere in the program. 
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Structures should be immutable</Name>
warnif count > 0 from t in JustMyCode.Types where 
   t.IsStructure && 
  !t.IsImmutable

let mutableFields = t.Fields.Where(f => !f.IsImmutable)

select new {
   t, 
   t.NbLinesOfCode, 
   mutableFields,
   Debt = (3+2*mutableFields.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// An object is immutable if its state doesn’t change once the 
// object has been created. Consequently, a structure or a class 
// is immutable if its instances fields are only assigned inline
// or from constructor(s).
//
// But for structure it is a bit different. **Structures are value
// types** which means instances of structures are copied when they are 
// passed around (like through a method argument).
//
// So if you change a copy you are changing only that copy, not the  
// original and not any other copies which might be around. Such 
// situation is very different than what happen with instances of 
// classes. Hence developers are not used to work with modified values
// and doing so introduces *confusion* and is *error-prone*. 
//</Description>

//<HowToFix>
// Make sure matched structures are immutable. This way, all 
// automatic copies of an original instance, resulting from being 
// *passed by value* will hold the same values and there will be 
// no surprises.
//
// If your structure is immutable then if you want to change 
// a value, you have to consciously do it by creating a new instance 
// of the structure with the modified data.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Property Getters should be immutable</Name>
warnif count > 0 from m in Application.Methods where
 !m.IsGeneratedByCompiler &&
  m.IsPropertyGetter &&
  ( ( !m.IsStatic && m.ChangesObjectState) ||
    (  m.IsStatic && m.ChangesTypeState) )

let setterSimpleName = "set_" + m.SimpleName.Substring(4,m.SimpleName.Length-4)

// Don't count field that are assigned only by the property getter and the related property setter.
let fieldsAssigned = m.FieldsAssigned.Where(f => 
          f.MethodsAssigningMe.Any(m1 => m1 != m && 
                                       !(m1.IsPropertySetter && m1.SimpleName == setterSimpleName)))
where fieldsAssigned.Any()
let otherMethodsAssigningSameFields = fieldsAssigned.SelectMany(f => f.MethodsAssigningMe.Where(m1 => m1 != m))

select new {
   m, 
   m.NbLinesOfCode, 
   fieldsAssigned,
   otherMethodsAssigningSameFields,
   Debt = (2 + 5*fieldsAssigned.Count() + 5*otherMethodsAssigningSameFields.Count() ).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// It is not expected that a state gets modified when 
// accessing a property getter. Hence doing so create
// confusion and property getters should be pure methods, 
// they shouldn't assign any field.
//
// This rule doesn't match property getters that assign a field
// not assigned by any other methods than the getter itself
// and the corresponding property setter. Hence this rule avoids 
// matching *lazy initialization at first access* of a state. 
// In such situation the getter assigns a field at first access
// and from the client point of view, lazy initialization
// is an invisible implementation detail.
//</Description>

//<HowToFix>
// Make sure that matched property getters don't assign any
// field.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 2 minutes plus 5 minutes per field assigned and
// 5 minutes per other method assigning such field.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>A field must not be assigned from outside its parent hierarchy types</Name>
        
warnif count > 0
from f in JustMyCode.Fields.Where(f => 
      (f.IsInternal || f.IsPublic) && 
      !f.IsGeneratedByCompiler && 
      !f.IsImmutable && 
      !f.IsEnumValue)

let methodsAssignerOutsideOfMyType = f.MethodsAssigningMe.Where(
     m =>!m.IsGeneratedByCompiler &&
          m.ParentType != f.ParentType && 
         !m.ParentType.DeriveFrom(f.ParentType) )

where methodsAssignerOutsideOfMyType.Any()

select new { 
   f, 
   methodsAssignerOutsideOfMyType,
   Debt = (5*methodsAssignerOutsideOfMyType.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is related to the rule *Fields should be declared as 
// private*. It matches any **public or internal, mutable field** 
// that is assigned from outside its parent class and subclasses.
//
// Fields should be considered as **implementation details**
// and as a consequence they should be declared as private.
//
// If something goes wrong with a *non-private field*, 
// the culprit can be anywhere, and so in order to track down 
// the bug, you may have to look at quite a lot of code.
//
// A private field, by contrast, can only be assigned from 
// inside the same class, so if something goes wrong with that, 
// there is usually only one source file to look at. 
//</Description>

//<HowToFix>
// Matched fields must be declared as *protected* and even better
// as *private*. 
//
// Alternatively, if the field can reference immutable states, 
// it can remain visible from the outside, but then must be 
// declared as *readonly*.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 5 minutes per method outside the parent hierarchy
// that assigns the matched field.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Don't assign a field from many methods</Name>
                
warnif count > 0 
from f in JustMyCode.Fields where 
  !f.IsEnumValue &&
  !f.IsImmutable && 
  !f.IsInitOnly &&
  !f.IsGeneratedByCompiler &&
  !f.IsEventDelegateObject

let methodsAssigningMe = f.MethodsAssigningMe.Where(m => !m.IsConstructor)

// The threshold 4 is arbitrary and it should avoid matching too many fields.
// Threshold is even lower for static fields because this reveals situations even more complex.
where methodsAssigningMe.Count() >= (!f.IsStatic ? 4 : 2)

select new { 
   f, 
   methodsAssigningMe, 
   f.MethodsReadingMeButNotAssigningMe, 
   f.MethodsUsingMe,
   Debt = (4+(f.IsStatic ? 10 : 5)).ToMinutes().ToDebt(),
   Severity = Severity.High
} 

//<Description>
// A field assigned from many methods is a symptom of **bug-prone code**.
// Notice that:
//
// • For an instance field, constructor(s) of its class that assign the field are not counted.
//
// • For a static field, the class constructor that assigns the field is not counted.
//
// The default threshold for *instance fields* is equal to *4 or more than 4 methods
// assigning the instance field*. Such situation makes harder to anticipate the 
// field state at runtime. The code is then complicated to read, hard to debug 
// and hard to maintain. Hard-to-solve bugs due to corrupted state are often the 
// consequence of fields *anarchically assigned*.
//
// The situation is even more complicated if the field is *static*.
// Indeed, such situation potentially involves global random accesses from
// various parts of the application. This is why this rule provides a lower 
// threshold equals to *2 or more than 2 methods assigning the static field*.
// 
// If the object containing such field is meant to be used from multiple threads, 
// there are **alarming chances** that the code is unmaintainable and bugged.
// When multiple threads are involved, the rule of thumb is to use immutable objects.
//
// If the field type is a reference type (interfaces, classes, strings, delegates) 
// corrupted state might result in a *NullReferenceException*.
// If the field type is a value type (number, boolean, structure) 
// corrupted state might result in wrong result not even signaled by an exception 
// thrown.
//</Description>

//<HowToFix>
// There is no straight advice to refactor the number of methods responsible 
// for assigning a field. Sometime the situation is simple enough, like when
// a field that hold an indentation state is assigned by many writer methods.
// Such situation only requires to define two methods *IndentPlus()/IndentMinus()* 
// that assign the field, called from all writers methods.
//
// Sometime the solution involves rethinking and then rewriting 
// a complex algorithm. Such field can sometime become just a variable accessed 
// locally by a method or a *closure*. Sometime, just rethinking the life-time 
// and the role of the parent object allows the field to become immutable 
// (i.e assigned only by the constructor).
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 4 minutes plus 5 minutes per method assigning the instance field
// or 10 minutes per method assigning the static field.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Do not declare read only mutable reference types</Name>
warnif count > 0 
from f in JustMyCode.Fields where 
   f.IsInitOnly && 
  !f.ParentType.IsPrivate &&
  !f.IsPrivate &&
   f.FieldType != null &&
   f.FieldType.IsClass &&
  !f.FieldType.IsThirdParty &&
  !f.FieldType.IsImmutable
select new { 
   f, 
   f.FieldType, 
   FieldVisibility = f.Visibility,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// This rule is violated when a *public* or *internal*  
// type contains a *public* or *internal* read-only field 
// whose field type is a mutable reference type.
//
// This situation gives the false impression that the 
// value can't change, when actually it's only the field 
// value that can't change, but the object state 
// can still change. 
//</Description>

//<HowToFix>
// To fix a violation of this rule, 
// replace the field type with an immutable type,
// or declare the field as *private*.
//
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Array fields should not be read only</Name>
warnif count > 0 
from f in Application.Fields where 
   f.IsInitOnly && 
   f.IsPubliclyVisible &&
   f.FieldType != null &&
   f.FieldType.FullName == "System.Array"
select new { 
   f, 
   FieldVisibility = f.Visibility,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// This rule is violated when a publicly visible field
// that holds an array, is declared read-only.
//
// This situation represents a *security vulnerability*.
// Because the field is read-only it cannot be changed to refer
// to a different array. However, the elements of the array 
// that are stored in a read-only field can be changed. 
// Code that makes decisions or performs operations that are 
// based on the elements of a read-only array that can be publicly 
// accessed might contain an exploitable security vulnerability.
//</Description>

//<HowToFix>
// To fix the security vulnerability that is identified by
// this rule do not rely on the contents of a read-only array 
// that can be publicly accessed. It is strongly recommended 
// that you use one of the following procedures:
//
// • Replace the array with a strongly typed collection 
// that cannot be changed. See for example: 
// *System.Collections.Generic.IReadOnlyList<T>* ;
// *System.Collections.Generic.IReadOnlyCollection<T>* ;
// *System.Collections.ReadOnlyCollectionBase*
//
// • Or replace the public field with a method that returns a clone 
// of a private array. Because your code does not rely on 
// the clone, there is no danger if the elements are modified.
//
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types tagged with ImmutableAttribute must be immutable</Name>
warnif count > 0 
from t in Application.Types where 
   t.HasAttribute ("NDepend.Attributes.ImmutableAttribute".AllowNoMatch()) && 
  !t.IsImmutable
let culpritFields = t.Fields.Where(f => !f.IsStatic && !f.IsImmutable)
select new { 
   t, 
   culpritFields,
   Debt = (5+10*culpritFields.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// An object is immutable if its state doesn’t change once the 
// object has been created. Consequently, a structure or a class 
// is immutable if its instances fields are only assigned inline
// or from constructor(s).
//
// An attribute **NDepend.Attributes.ImmutableAttribute** can be 
// used to express in code that a type is immutable. In such 
// situation, the present code rule checks continuously that the 
// type remains immutable whatever the modification done.
//
// This rule warns when a type that is tagged with
// *ImmutableAttribute* is actually not immutable anymore.
//
// Notice that *FullCoveredAttribute* is defined in *NDepend.API.dll*
// and if you don't want to link this assembly, you can create your
// own  *FullCoveredAttribute* and adapt the rule.
//</Description>

//<HowToFix>
// First understand which modification broke the type immutability.
// The list of *culpritFields* provided in this rule result can help.
// Then try to refactor the type to bring it back to immutability.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 5 minutes plus 10 minutes per culprit field.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types immutable should be tagged with ImmutableAttribute</Name>

// warnif count > 0   <-- not a code rule per default

from t in Application.Types where 
  !t.HasAttribute ("NDepend.Attributes.ImmutableAttribute".AllowNoMatch()) && 
   t.IsImmutable
select new { 
   t, 
   t.NbLinesOfCode,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// An object is immutable if its state doesn’t change once the 
// object has been created. Consequently, a structure or a class 
// is immutable if its instances fields are only assigned inline
// or from constructor(s).
//
// This code query lists immutable type that are not tagged with
// an **ImmutableAttribute**. By using such attribute, you can express
// in source code the intention that a class is immutable, and 
// should remain immutable in the future. Benefits of using 
// an **ImmutableAttribute** are twofold:
//
// • Not only the intention is expressed in source code,
//
// • but it is also continuously checked by the rule 
// *Types tagged with ImmutableAttribute must be immutable*.
//</Description>

//<HowToFix>
// Just tag types matched by this code query with **ImmutableAttribute**
// that can be found in *NDepend.API.dll*,
// or by an attribute of yours defined in your own code 
// (in which case this code query must be adapted).
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods tagged with PureAttribute must be pure</Name>

warnif count > 0 
from m in Application.Methods where 
  ( m.HasAttribute ("NDepend.Attributes.PureAttribute".AllowNoMatch()) || 
    m.HasAttribute ("System.Diagnostics.Contract.PureAttribute".AllowNoMatch()) ) &&
  ( m.ChangesObjectState || m.ChangesTypeState ) &&
    m.NbLinesOfCode > 0

let fieldsAssigned = m.FieldsAssigned

select new { 
   m, 
   m.NbLinesOfCode, 
   fieldsAssigned,
   Debt = 15.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// A method is pure if its execution doesn’t change 
// the value of any instance or static field.
// A pure method is just a **function** that output 
// a result from inputs.
// Pure methods naturally simplify code by **limiting 
// side-effects**. 
//
// An attribute **PureAttribute** can be 
// used to express in code that a method is pure. In such 
// situation, the present code rule checks continuously that the 
// method remains pure whatever the modification done.
//
// This rule warns when a method that is tagged with
// *PureAttribute* is actually not pure anymore.
//
// Notice that *NDepend.Attributes.PureAttribute* is defined 
// in *NDepend.API.dll* and if you don't want to link this 
// assembly, you can also use 
// *System.Diagnostics.Contract.PureAttribute*
// or create your own *PureAttribute* and adapt the rule.
// 
// Notice that *System.Diagnostics.Contract.PureAttribute* is 
// taken account by the compiler only when the VS project has 
// Microsoft Code Contract enabled. 
//</Description>

//<HowToFix>
// First understand which modification broke the method purity.
// Then refactor the method to bring it back to purity. 
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Pure methods should be tagged with PureAttribute</Name>

// warnif count > 0   <-- not a code rule per default

from m in Application.Methods where 
  !m.IsGeneratedByCompiler &&
  !m.HasAttribute ("NDepend.Attributes.PureAttribute".AllowNoMatch()) && 
  !m.HasAttribute ("System.Diagnostics.Contract.PureAttribute".AllowNoMatch()) &&
  !m.ChangesObjectState && !m.ChangesTypeState &&
   m.NbLinesOfCode > 0
select new {
   m, 
   m.NbLinesOfCode,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// A method is pure if its execution doesn’t change 
// the value of any instance or static field. 
// Pure methods naturally simplify code by **limiting 
// side-effects**.
//
// This code query lists pure methods that are not tagged with
// a **PureAttribute**. By using such attribute, you can express
// in source code the intention that a method is pure, and 
// should remain pure in the future. Benefits of using 
// a **PureAttribute** are twofold:
//
// • Not only the intention is expressed in source code,
//
// • but it is also continuously checked by the rule 
// *Methods tagged with PureAttribute must be pure*.
//
// This code query is not by default defined as a code rule
// because certainly many of the methods of the code base 
// are matched. Hence fixing all matches and then
// maintaining the rule unviolated might require a lot of
// work. This may *counter-balance* such rule benefits.
//</Description>

//<HowToFix>
// Just tag methods matched by this code query with
// *NDepend.Attributes.PureAttribute*
// that can be found in *NDepend.API.dll*,
// or with *System.Diagnostics.Contract.PureAttribute*,
// or with an attribute of yours defined in your own code 
// (in which case this code query must be adapted).
//
// Notice that *System.Diagnostics.Contract.PureAttribute* is 
// taken account by the compiler only when the VS project has 
// Microsoft Code Contract enabled. 
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Rules violated</Name>
from r in Rules
where r.IsViolated()
orderby r.Debt().Value descending
select new { 
   r, 
   Issues = r.Issues(), 
   Debt = r.Debt(), 
   AnnualInterest = r.AnnualInterest(), 
   BreakingPoint = r.BreakingPoint(),
   Category = r.Category
}

//<Description>
// **Debt**: Estimated effort to fix all rule issues.
//
// **Annual Interest**: Estimated annual cost to leave all rule issues unfixed.
//
// **Breaking Point**: Estimated point in time from now, when leaving the rule issues unfixed cost as much as fixing the rule issues.
// A low value indicates an a rule with easy-to-fix issue with high annual interest.
// This value can be used to prioritize issues fix, to significantly reduce interest with minimum effort.
//
// More documentation: http://www.ndepend.com/docs/technical-debt
//</Description>]]></Query>
    </Group>
    <Group Name="Naming Conventions" Active="True" ShownInReport="False">
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Instance fields naming convention</Name>
warnif count > 0 from f in JustMyCode.Fields where 
  !( 
    // Instance field name starting with a lower-case letter
    (f.Name.Length >= 1 && char.IsLetter(f.Name[0]) && char.IsLower(f.Name[0])) ||

    // Instance field name starting with "_" followed with a lower-case letter
    (f.Name.Length >= 2 && f.Name.StartsWith("_") && char.IsLetter(f.Name[1]) && char.IsLower(f.Name[1])) ||

    // Instance field name starting with "m_" followed with an upper-case letter
    (f.Name.Length >= 3 && f.Name.StartsWith("m_") && char.IsLetter(f.Name[2]) && char.IsUpper(f.Name[2])) 

  ) &&
  !f.IsStatic && 
  !f.IsLiteral && 
  !f.IsGeneratedByCompiler  && 
  !f.IsSpecialName && 
  !f.IsEventDelegateObject &&
  
   // Don't check naming convention on serializable fields
  !f.HasAttribute("System.Xml.Serialization.XmlAttributeAttribute".AllowNoMatch()) &&
  !f.HasAttribute("System.Runtime.Serialization.DataMemberAttribute".AllowNoMatch()) &&
  
   // Don't warn if a method using the field is also calling a method that has 'ref' and 'out' parameters.
   // This could lead to false positive. A field used in a 'ref' or 'out' parameter cannot be set as read-only.
   f.MethodsUsingMe.SelectMany(m => m.MethodsCalled).FirstOrDefault(m => m.Name.Contains("&")) == null 
  
select new {
   f,
   f.SizeOfInst,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Description>
// By default the presents rule supports the 3 most used naming
// conventions for instance fields:
//
// • Instance field name starting with a lower-case letter
//
// • Instance field name starting with "_" followed with a lower-case letter
//
// • Instance field name starting with "m_" followed with an upper-case letter
//
// The rule can be easily adapted to your own company naming convention.
//
// In terms of behavior, a *static field* is something completely different
// than an *instance field*, so it is interesting to differentiate them at 
// a glance through a naming convetion.
//
// This is why it is advised to use a specific naming convention for instance 
// field like name that starts with **m_**.
//
// Related discussion:
// http://codebetter.com/patricksmacchia/2013/09/04/on-hungarian-notation-for-instance-vs-static-fields-naming/
//</Description>

//<HowToFix>
// Once the rule has been adapted to your own naming convention
// make sure to name all matched instance fields adequately.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Static fields naming convention</Name>
warnif count > 0 from f in Application.Fields where 
  !( 
    // Static field name starting with an upper-case letter
    (f.Name.Length >= 1 && char.IsLetter(f.Name[0]) && char.IsUpper(f.Name[0])) ||

    // Static field name starting with "_" followed with an upper-case letter
    (f.Name.Length >= 2 && f.Name.StartsWith("_") && char.IsLetter(f.Name[1]) && char.IsUpper(f.Name[1])) ||

    // Static field name starting with "s_" followed with an upper-case letter
    (f.Name.Length >= 3 && f.Name.StartsWith("s_") && char.IsLetter(f.Name[2]) && char.IsUpper(f.Name[2])) 

  ) &&
   f.IsStatic && 
  !f.IsLiteral && 
  !f.IsGeneratedByCompiler && 
  !f.IsSpecialName && 
  !f.IsEventDelegateObject
select new {
   f,
   f.SizeOfInst,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}  

//<Description>
// By default the presents rule supports the 3 most used naming
// conventions for static fields:
//
// • Static field name starting with an upper-case letter
//
// • Static field name starting with "_" followed with an upper-case letter
//
// • Static field name starting with "s_" followed with an upper-case letter
//
// The rule can be easily adapted to your own company naming convention.
//
// In terms of behavior, a *static field* is something completely different
// than an *instance field*, so it is interesting to differentiate them at 
// a glance through a naming convetion.
//
// This is why it is advised to use a specific naming convention for static 
// field like name that starts with **s_**.
//
// Related discussion:
// http://codebetter.com/patricksmacchia/2013/09/04/on-hungarian-notation-for-instance-vs-static-fields-naming/
//</Description>

//<HowToFix>
// Once the rule has been adapted to your own naming convention
// make sure to name all matched static fields adequately.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Interface name should begin with a 'I'</Name>
   
// Don't query all Application.Types because some interface generated might not start with an 'I' 
// like for example when adding a WSDL reference to a project.
warnif count > 0 from t in JustMyCode.Types where 
   t.IsInterface  &&
   // Don't apply this rule for COM interfaces.
  !t.HasAttribute("System.Runtime.InteropServices.ComVisibleAttribute".AllowNoMatch())

// Discard outter type(s) name prefix for nested types
let name = !t.IsNested  ? 
   t.Name : 
   t.Name.Substring(t.Name.LastIndexOf('+') + 1, t.Name.Length - t.Name.LastIndexOf('+') - 1) 

where name[0] != 'I'
select new { 
   t,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// In the .NET world, interfaces names are commonly prefixed
// with an upper case **I**. This rule warns about interfaces
// whose names don't follow this convention. Because this 
// naming convention is widely used and accepted, we 
// recommend abiding by this rule.
//
// Typically COM interfaces names don't follow this rule.
// Hence this code rule doesn't take care of interfaces tagged
// with *ComVisibleAttribute*.
//</Description>

//<HowToFix>
// Make sure that matched interfaces names are prefixed with
// an upper **I**.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Abstract base class should be suffixed with 'Base'</Name>
        
warnif count > 0 from t in Application.Types where 
  t.IsAbstract && 
  t.IsClass &&

  t.BaseClass != null &&
  t.BaseClass.FullName == "System.Object" &&

  ((!t.IsGeneric && !t.NameLike (@"Base$")) ||
   ( t.IsGeneric && !t.NameLike (@"Base<")))
select new {
   t,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule warns about *abstract classes* whose names are not 
// suffixed with **Base**. It is a common practice in the .NET 
// world to suffix base classes names with **Base**.
//
// Notice that this rule doesn't match abstract classes that 
// are in a middle of a hierarchy chain.
// In other words, only base classes that derive directly 
// from *System.Object* are matched.
//</Description>

//<HowToFix>
// Suffix the names of matched base classes with **Base**.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Exception class name should be suffixed with 'Exception'</Name>
warnif count > 0 from t in Application.Types where 
  t.IsExceptionClass &&
  
  // We use SimpleName, because in case of generic Exception type
  // SimpleName suppresses the generic suffix (like <T>).
 !t.SimpleNameLike(@"Exception$") &&
 !t.SimpleNameLike(@"ExceptionBase$") // Allow the second suffix Base
                                      // for base exception classes.
select new {
   t,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns about *exception classes* whose names are not 
// suffixed with **Exception**. It is a common practice in the .NET 
// world to suffix exception classes names with **Exception**.
//
// For exception base classes, the suffix **ExceptionBase**
// is also accepted.
//</Description>

//<HowToFix>
// Suffix the names of matched exception classes with **Exception**.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Attribute class name should be suffixed with 'Attribute'</Name>
warnif count > 0 from t in Application.Types where 
   t.IsAttributeClass && 
  !t.NameLike (@"Attribute$") 
select new {
   t,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns about *attribute classes* whose names are not 
// suffixed with **Attribute**. It is a common practice in the .NET 
// world to suffix attribute classes names with **Attribute**.
//</Description>

//<HowToFix>
// Suffix the names of matched attribute classes with **Attribute**.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types name should begin with an Upper character</Name>
warnif count > 0 
from t in JustMyCode.Types where 
  // The name of a type should begin with an Upper letter.
  !t.SimpleNameLike (@"^[A-Z]") &&     

  // Except if it is generated by compiler.
  !t.IsSpecialName &&
  !t.IsGeneratedByCompiler

select new { 
   t,
   // We show the type simple name
   // that doesn't include the parent type name
   // for nested types. 
   t.SimpleName,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule warns about *types* whose names don't start
// with an Upper character. It is a common practice in the .NET 
// world to use **Pascal Casing Style** to name types.
//
// **Pascal Casing Style** : The first letter in the identifier 
// and the first letter of each subsequent concatenated word 
// are capitalized. For example:  *BackColor*
//</Description>

//<HowToFix>
// *Pascal Case* the names of matched types.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods name should begin with an Upper character</Name>
warnif count > 0 
from m in JustMyCode.Methods where 
  !m.NameLike (@"^[A-Z]") && 
  !m.IsSpecialName && 
  !m.IsGeneratedByCompiler
select new {
   m,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule warns about *methods* whose names don't start
// with an Upper character. It is a common practice in the .NET 
// world to use **Pascal Casing Style** to name methods.
//
// **Pascal Casing Style** : The first letter in the identifier 
// and the first letter of each subsequent concatenated word 
// are capitalized. For example:  *ComputeSize*
//</Description>

//<HowToFix>
// *Pascal Case* the names of matched methods.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Do not name enum values 'Reserved'</Name>
warnif count > 0 
from f in Application.Fields where 
  f.IsEnumValue && 
  f.NameLike (@"Reserved")
select new {
   f,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule assumes that an enumeration member 
// with a name that contains **"Reserved"** 
// is not currently used but is a placeholder to 
// be renamed or removed in a future version.
// Renaming or removing a member is a breaking 
// change. You should not expect users to ignore
// a member just because its name contains 
// **"Reserved"** nor can you rely on users to read or 
// abide by documentation. Furthermore, because 
// reserved members appear in object browsers 
// and smart integrated development environments, 
// they can cause confusion as to which members 
// are actually being used.
//
// Instead of using a reserved member, add a 
// new member to the enumeration in the future 
// version.
//
// In most cases, the addition of the new 
// member is not a breaking change, as long as the 
// addition does not cause the values of the 
// original members to change.
//</Description>

//<HowToFix>
// To fix a violation of this rule, remove or 
// rename the member.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid types with name too long</Name>
warnif count > 0 
from t in JustMyCode.Types 
where !t.IsGeneratedByCompiler

where t.SimpleName.Length > 40 
orderby t.SimpleName.Length descending
select new {
   t, 
   t.SimpleName,
   NameLength = t.SimpleName.Length,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Types with a name too long tend to decrease code readability.
// This might also be an indication that a type is doing too much.
//
// This rule matches types with names with more than 40 characters.
//</Description>

//<HowToFix>
// To fix a violation of this rule, rename the type with a shortest name
// or eventually split the type in several more fine-grained types.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid methods with name too long</Name>
warnif count > 0 from m in JustMyCode.Methods where 

 // Explicit Interface Implementation methods are 
 // discarded because their names are prefixed 
 // with the interface name.
 !m.IsExplicitInterfaceImpl &&
 !m.IsGeneratedByCompiler &&
 ((!m.IsSpecialName && m.SimpleName.Length > 40) ||
   // Property getter/setter are prefixed with "get_" "set_" of length 4.
  ( m.IsSpecialName && m.SimpleName.Length - 4 > 40))

orderby m.SimpleName.Length descending

select new { 
   m, 
   m.SimpleName,
   NameLength = m.SimpleName.Length - (m.IsSpecialName ? 4 : 0),
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Methods with a name too long tend to decrease code readability.
// This might also be an indication that a method is doing too much.
//
// This rule matches methods with names with more than 40 characters.
//</Description>

//<HowToFix>
// To fix a violation of this rule, rename the method with a shortest name
// that equally conveys the behavior of the method.
// Or eventually split the method into several smaller methods.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid fields with name too long</Name>
warnif count > 0 from f in JustMyCode.Fields where
 !f.IsGeneratedByCompiler &&
  f.Name.Length > 40
orderby f.Name descending
select new {
   f,
   NameLength = f.Name.Length,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Fields with a name too long tend to decrease code readability.
//
// This rule matches fields with names with more than 40 characters.
//</Description>

//<HowToFix>
// To fix a violation of this rule, rename the field with a shortest name
// that equally conveys the same information.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid having different types with same name</Name>
warnif count > 0

// Special type names for which multiple types with such name are allowed.
let nonReportedTypeName = new [] { "Program", "NamespaceDoc" }

// This rule matches also collisions between 
// application and third-party types sharing a same name.
let groups = JustMyCode.Types.Union(ThirdParty.Types)
                 // Discard nested types, whose name is
                 // prefixed with the parent type name.
                 .Where(t => !t.IsNested && !nonReportedTypeName.Contains(t.Name))
                 
                 // Group types by name.
                 .GroupBy(t => t.Name)

from @group in groups 
   where @group.Count() > 1

   // Let's see if types with the same name are declared
   // in different namespaces.
   // (t.FullName is {namespaceName}.{typeName} )
   let groupsFullName = @group.GroupBy(t => t.FullName)
   where groupsFullName.Count() > 1

   // If several types with same name are declared in different namespaces
   // eliminate the case where all types are declared in third-party assemblies.
   let types= groupsFullName.SelectMany(g => g)
   where types.Any(t => !t.IsThirdParty)
        // Uncomment this line, to only gets naming collision involving
        // both application and third-party types.
        //         && types.Any(t => t.IsThirdParty)

orderby types.Count() descending 

select new { 
   // Order types by parent namespace and assembly name,this  way we always get the same type across sessions.
   // Without this astute, the same issue would be seen as added/removed when the first type choosen in the group
   // was not always the same, a situation that actually happens.
   // Also make sure that the chosen type is not a third-party one.
   t = types.OrderBy(t => (t.IsThirdParty ? "1" : "0") + t.ParentNamespace.Name + t.ParentAssembly.Name).First(),
   
   // In the 'types' column, make sure to group matched types 
   // by parent assemblies and parent namespaces, to get a result
   // more readable.
   types,
   
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns about multiple types with same name,
// that are defined in different *application* or  
// *third-party* namespaces or assemblies.
//
// Such practice create confusion and also naming collision
// in source files that use different types with same name.
//</Description>

//<HowToFix>
// To fix a violation of this rule, rename concerned types.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid prefixing type name with parent namespace name</Name>
warnif count > 0

from n in JustMyCode.Namespaces
where n.Name.Length > 0

from t in n.ChildTypes
where 
   JustMyCode.Contains(t) && // Don't warn about generated code 
  !t.IsGeneratedByCompiler &&
  !t.IsNested &&
   t.Name.IndexOf(n.SimpleName) == 0 &&

  // The type name is equal to namespace name or the type name contains another
  // word that starts with an upper-case letter after the namespace name.
  // This way we avoid matching false-positive where namespace name is "Stat" and type name is "Statistic".
  (t.Name.Length == n.SimpleName.Length || char.IsUpper(t.Name[n.SimpleName.Length]))
select new { 
   t, 
   namespaceName = n.SimpleName,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule warns about situations where the parent namespace name
// is used as the prefix of a contained type.
//
// For example a type named "RuntimeEnvironment"
// declared in a namespace named "Foo.Runtime"
// should be named "Environment".
//
// Such situation creates naming redundancy with no readability gain.
//</Description>

//<HowToFix>
// To fix a violation of this rule, remove the prefix from the type name.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid naming types and namespaces with the same identifier</Name>
warnif count > 0
let hashsetShortNames = Namespaces.Where(n => n.Name.Length > 0).Select(n => n.SimpleName).ToHashSet()

from t in JustMyCode.Types
where hashsetShortNames.Contains(t.Name)
select new { 
   t, 
   namespaces = Namespaces.Where(n => n.SimpleName == t.Name),
   Debt = 12.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns when a type and a namespace have the same name.
//
// For example when a type is named *Environment*
// and a namespace is named *Foo.Environment*.
//
// Such situation provokes tedious compiler resolution collision,
// and makes the code less readable because concepts are not 
// concisely identified.
//</Description>

//<HowToFix>
// To fix a violation of this rule, renamed the concerned type or namespace.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Don't call your method Dispose</Name>
warnif count > 0
from m in JustMyCode.Methods.WithSimpleName("Dispose")
where !m.ParentType.Implement("System.IDisposable".AllowNoMatch()) &&
       m.OverriddensBase.Count() == 0    // Can't change the name of an override
select new {
   m,
   Debt = 15.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// In .NET programming, the identifier *Dispose* should be kept 
// only for implementations of *System.IDisposable*.
//
// This rule warns when a method is named *Dispose()*,
// but the parent type doesn't implement *System.IDisposable*.
//</Description>

//<HowToFix>
// To fix a violation of this rule,
// either make the parent type implements *System.IDisposable*,
// or rename the *Dispose()* method with another identifier like:
// *Close() Terminate() Finish() Quit() Exit() Unlock() ShutDown()*…
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods prefixed with 'Try' should return a boolean</Name>
warnif count > 0
from m in Application.Methods where
  m.SimpleNameLike("^Try") &&
  m.ReturnType != null &&
  m.ReturnType.FullName != "System.Boolean"
select new { 
   m, 
   m.ReturnType,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// When a method has a name prefixed with **Try**, it is expected that
// it returns a *boolean*, that reflects the method execution status,
// *success* or *failure*.
//
// Such method usually returns a result through an *out parameter*.
// For example:  *System.Int32.TryParse(int,out string):bool*
//</Description>

//<HowToFix>
// To fix a violation of this rule,
// Rename the method, or transform it into an operation that can fail.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Quality Gates Evolution</Name>
from qg in QualityGates
let qgBaseline = qg.OlderVersion()
let relyOnDiff = qgBaseline == null
let evolution = relyOnDiff ? (TrendIcon?)null : 
                // When a quality gate relies on diff between now and baseline
                // it is not executed against the baseline
                qg.ValueDiff() == 0d ?
                TrendIcon.Constant :
                (qg.ValueDiff() > 0 ? 
                  ( qg.MoreIsBad ?  TrendIcon.RedUp: TrendIcon.GreenUp) :
                  (!qg.MoreIsBad ?  TrendIcon.RedDown: TrendIcon.GreenDown))
select new { qg, 
   Evolution      =  evolution,

   BaselineStatus =  relyOnDiff? (QualityGateStatus?) null : qgBaseline.Status,
   Status         =  qg.Status,

   BaselineValue  =  relyOnDiff? (null) : qgBaseline.ValueString,
   Value          =  qg.ValueString, 
}
 
// <Description>
// Show quality gates evolution between baseline and now.
//
// When a quality gate relies on diff between now and baseline (like *New Debt since Baseline*)
// it is not executed against the baseline and as a consequence its evolution is not available.
//
// Double-click a quality gate for editing.
// </Description>]]></Query>
    </Group>
    <Group Name="Source Files Organization" Active="True" ShownInReport="False">
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid referencing source file out of Visual Studio project directory</Name>
warnif count > 0 

from a in Application.Assemblies
where a.VisualStudioProjectFilePath != null
let vsProjDirPathLower = a.VisualStudioProjectFilePath.ParentDirectoryPath.ToString().ToLower()

from t in a.ChildTypes
where JustMyCode.Contains(t) && t.SourceFileDeclAvailable

from decl in t.SourceDecls
let sourceFilePathLower = decl.SourceFile.FilePath.ToString().ToLower()
where sourceFilePathLower.IndexOf(vsProjDirPathLower) != 0
select new { 
   t, 
   sourceFilePathLower, 
   projectFilePath = a.VisualStudioProjectFilePath.ToString(),
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// A source file located outside of the VS project directory can be added through:
// *> Add > Existing Items… > Add As Link*
//
// Doing so can be used to share types definitions across several assemblies.
// This provokes type duplication at binary level.
// Hence maintainability is degraded and subtle versioning bug can appear.
//
// This rule matches types whose source files are not declared under the 
// directory that contains the related Visual Studio project file, or under
// any sub-directory of this directory.
//
// This practice can be tolerated for certain types shared across executable assemblies.
// Such type can be responsible for startup related concerns, 
// such as registering custom assembly resolving handlers or 
// checking the .NET Framework version before loading any custom library.
//</Description>

//<HowToFix>
// To fix a violation of this rule, prefer referencing from a VS project
// only source files defined in sub-directories of the VS project file location.
//
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid duplicating a type definition across assemblies</Name>
warnif count > 0

let groups = Application.Types
             .Where(t => !t.IsGeneratedByCompiler)
             .GroupBy(t => t.FullName)
from @group in groups
where @group.Count() > 1

// Tricky: This rule is executed on both current snapshot and baseline snapshot (if any).
//         Taking t as @group.First() could return any type in the group, and potentially
//         it can return different types for current and baseline snapshot.
//         As a result issues wouldn't corresponds (since types are different) and the user 
//         would see issues of this rule as a couple of issues added and removed.
//         Ordering types by parent assembly name and then taking the first type, discards this risk. 
let types = @group.OrderBy(t => t.ParentAssembly.Name)

select new { 
   t = types.First(),
   // In the 'types' column, make sure to group matched types by parent assemblies.
   typesDefs = types.ToArray(),
   Debt = 15.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// A source file located outside of the VS project directory can be added through:
// *> Add > Existing Items… > Add As Link*
//
// This rule warns about using this feature to share code across several assemblies.
// This provokes type duplication at binary level.
// Hence maintainability is degraded and subtle versioning bug can appear.
//
// This practice can be tolerated for certain types shared across executable assemblies.
// Such type can be responsible for startup related concerns, 
// such as registering custom assembly resolving handlers or 
// checking the .NET Framework version before loading any custom library.
//</Description>

//<HowToFix>
// To fix a violation of this rule, prefer sharing types through DLLs.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid defining multiple types in a source file</Name>
warnif count > 0 

// Build a lookup indexed by source files, values being a sequence of types defined in the source file.
let lookup = JustMyCode.Types
              // When a source file is referenced by several assemblies, 
              // type(s) contained in the source file are seen as distinct types, both by the CLR and by NDepend.
              // This Distinct clause based on type full-name (type name prefixed with namespace) 
              // avoids matching the multiple versions of such type.
             .Distinct(t => t.FullName)
             .Where(t => t.SourceFileDeclAvailable && 
                         // except enumerations, nested types and types generated by compilers!
                        !t.IsEnumeration &&          
                        !t.IsNested &&                   
                        !t.IsGeneratedByCompiler)
             // We use multi-key, since a type can be declared in multiple source files.
             .ToMultiKeyLookup(t => t.SourceDecls.Select(d => d.SourceFile))
 
from @group in lookup where @group.Count() > 1
   let sourceFile = @group.Key

   // CQLinq doesn't let indexing result with sourceFile 
   // so we choose a typeIndex in types, 
   // preferably the type that has the file name.
   let typeWithSourceFileName = @group.FirstOrDefault(t => t.SimpleName == sourceFile.FileNameWithoutExtension)
   let typeIndex = typeWithSourceFileName ?? @group.First()

select new { 
   typeIndex, 
   TypesInSourceFile = @group as IEnumerable<IType>, 
   SourceFilePathString = sourceFile.FilePathString,
   Debt = 3.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// Defining multiple types in a single source file decreases code readability,
// because developers are used to see all types in a namespace,
// when expanding a folder in the *Visual Studio Solution Explorer*.
// Also doing so, leads to source files with too many lines.
//
// Each match of this rule is a source file that contains several types
// definitions, indexed by one of those types, preferably the one with
// the same name than the source file name without file extension, if any.
//</Description>

//<HowToFix>
// To fix a violation of this rule, create a source file for each type.
//
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</HowToFix>]]></Query>
      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Namespace name should correspond to file location</Name>
warnif count > 0
from n in Application.Namespaces 

// Replace dots by spaces in namespace name
let dirCorrespondingAll = n.Name.Replace('.', ' ')

// Remove the first namespace component that is typically the product name
// and that typically interfere with assemblies names.
let dirCorresponding = !dirCorrespondingAll.Contains(' ') ? 
        dirCorrespondingAll : 
        dirCorrespondingAll.Substring(dirCorrespondingAll.IndexOf(' ')+1, dirCorrespondingAll.Length - dirCorrespondingAll.IndexOf(' ') - 1)


// Look at source file decl of JustMyCode type's declared in n
from t in n.ChildTypes
where JustMyCode.Contains(t) && t.SourceFileDeclAvailable

let sourceDeclConcerned = (from decl in t.SourceDecls
                           let sourceFilePath = decl.SourceFile.FilePath.ToString()
                           // Replace dots and path separators by spaces in source files names
                           where !sourceFilePath.Replace('.',' ').Replace('\\',' ').Contains(dirCorresponding)
                           select sourceFilePath).ToArray()
where sourceDeclConcerned.Length > 0


select new { 
   t, 
   dirCorresponding , 
   sourceFilePath = sourceDeclConcerned[0],
   nbSourceDeclConcerned = sourceDeclConcerned.Length,
   Debt = (2 + sourceDeclConcerned.Length).ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Description>
// For a solid code structure and organization, 
// do mirror the namespaces hierarchy and the directories hierarchy containing source files.
//
// Doing so is a widely accepted convention, and not respecting this convention 
// will lead to less maintainable and less browsable source code.
//
// This rule matches all types in such source file, whose location doesn't correspond
// to the type parent namespace. If a source file contains several such types (that
// are not necessarily in the same namespace) each type will result in a violation.
//
// If a type is declared in several such source files, the value for the column
// *nbSourceDeclConcerned* in the result, is greater than 1.
// The technical-debt per issue is proportional to *nbSourceDeclConcerned*.
//</Description>

//<HowToFix>
// To fix a violation of this rule, make sure that the type parent namespace and 
// the directory sub-paths that contains the type source file, are mirrored.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types with source files stored in the same directory, should be declared in the same namespace</Name>
warnif count > 0 

// Group JustMyCode types in a lookup 
// where groups are keyed with directories that contain the types' source file(s).
// Note that a type can be contained in several groups 
// if it is declared in several source files stored in different directories.
let lookup = JustMyCode.Types.Where(t => t.SourceFileDeclAvailable)
            .ToMultiKeyLookup(
               t => t.SourceDecls.Select(
                          decl => decl.SourceFile.FilePath.ParentDirectoryPath).Distinct()
            )

from groupOfTypes in lookup
let parentNamespaces = groupOfTypes.ParentNamespaces()

// Select group of types (with source files stored in the same directory) …
// … but contained in several namespaces
where parentNamespaces.Count() > 1

// mainNamespaces is the namespace that contains many types 
// declared in the directory groupOfTypes .key
let mainNamespace  = groupOfTypes
                     .ToLookup(t => t.ParentNamespace)
                     .OrderByDescending(g => g.Count()).First().Key

// Select types with source files stored in the same directory,
// but contained in namespaces different than mainNamespace.
let typesOutOfMainNamespace = groupOfTypes
                              .Where(t => t.ParentNamespace != mainNamespace &&
                                          t.ParentAssembly == mainNamespace.ParentAssembly)

                              // Filter types declared on several source files that contain generated methods 
                              // because typically such type contains one or several partial definitions generated.
                              // These partially generated types would be false positive for the present rule.
                              .Where(t => t.SourceDecls.Count() == 1 ||
                                          t.Methods.Count(m => JustMyCode.Contains(m)) == 0)
where typesOutOfMainNamespace.Count() > 0

let typesInMainNamespace = groupOfTypes.Where(t => t.ParentNamespace == mainNamespace)

select new { 
   mainNamespace, 
   typesOutOfMainNamespace,
   typesInMainNamespace,
   Debt = (2+5*typesOutOfMainNamespace.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// For a solid code structure and organization, do mirror the namespaces 
// hierarchy and the directories hierarchy containing source files.
//
// Doing so is a widely accepted convention, and not respecting this convention 
// will lead to less maintainable and less browsable code.
//
// Respecting this convention means that types with source files stored in the same directory, 
// should be declared in the same namespace.
//
// For each directory that contains several source files, where most types are declared 
// in a namespace (what we call the **main namespace**) and a few types are declared 
// out of the *main namespace*, this code rule matches:
//
// • The *main namespace*
//
// • **typesOutOfMainNamespace**: Types declared in source files in the *main namespace*'s directory
// but that are not in the *main namespace*.
//
// • *typesInMainNamespace*: And for informational purposes, types declared in source files in the 
// *main namespace*'s directory, and that are in the *main namespace*.
//</Description>

//<HowToFix>
// Violations of this rule are types in the *typesOutOfMainNamespace* column.
// Typically such type …
//
// •  … is contained in the wrong namespace but its source file is stored in the right directory.
//    In such situation the type should be contained in *main namespace*.
//
// •  … is contained in the right namespace but its source file is stored in the wrong directory
//    In such situation the source file of the type must be moved to the proper parent namespace directory.
//
// •  … is declared in multiple source files, stored in different directories.
//    In such situation it is preferable that all source files are stored in a single directory.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 2 minutes plus 5 minutes per type in *typesOutOfMainNamespace*.
//</HowToFix>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types declared in the same namespace, should have their source files stored in the same directory</Name>
        
warnif count > 0 
from @namespace in Application.Namespaces

// Group types of @namespace in a lookup 
// where groups are keyed with directories that contain the types' source file(s).
// Note that a type can be contained in several groups 
// if it is declared in several source files stored in different directories.
let lookup = @namespace.ChildTypes.Where(t => t.SourceFileDeclAvailable && JustMyCode.Contains(t))
            .ToMultiKeyLookup(
               t => t.SourceDecls.Select(
                          decl => decl.SourceFile.FilePath.ParentDirectoryPath).Distinct()
            )

// Are types of @namespaces declared in more than one directory?
where lookup.Count > 1

// Infer the main folder, preferably the one that has the same name as the namespace.
let dirs = lookup.Select(types => types.Key)
let mainDirNullable = dirs.Where(d => d.DirectoryName == @namespace.SimpleName).FirstOrDefault()
let mainDir = mainDirNullable ?? dirs.First()

// Types declared out of mainDir, are types in group of types declared in a directory different than mainDir!
let typesDeclaredOutOfMainDir = 
   lookup.Where(types => types.Key != mainDir)
         .SelectMany(types => types)
                                
         // Filter types declared on several source files that contain generated methods 
         // because typically such type contains one or several partial definitions generated.
         // These partially generated types would be false positive for the present rule.
         .Where(t => t.SourceDecls.Count() == 1 ||
                     t.Methods.Count(m => JustMyCode.Contains(m)) == 0)

where typesDeclaredOutOfMainDir.Count() > 0

let typesDeclaredInMainDir = 
   lookup.Where(types => types.Key == mainDir)
         .SelectMany(types => types)

select new { 
   @namespace, 
   typesDeclaredOutOfMainDir, 
   mainDir = mainDir.ToString(),
   typesDeclaredInMainDir,
   Debt = (2+5*typesDeclaredOutOfMainDir.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// For a solid code structure and organization, 
// do mirror the namespaces hierarchy and the directories hierarchy containing source files.
//
// Doing so is a widely accepted convention, and not respecting this convention 
// will lead to less maintainable and less browsable code.
//
// Respecting this convention means that types declared in the same namespace,
// should have their source files stored in the same directory.
//
// For each namespace that contains types whose source files
// are declared in several directories, infer the **main directory**,
// the directory that naturally hosts source files of types,
// preferably the directory whose name corresponds with the namespace 
// name. In this context, this code rule matches:
//
// • The namespace
//
// • **typesDeclaredOutOfMainDir**: types in the namespace whose source files 
// are stored out of the *main directory*.
//
// • The *main directory*
//  
// • *typesDeclaredInMainDir*: for informational purposes, types declared 
// in the namespace, whose source files are stored in the *main directory*.
//</Description>

//<HowToFix>
// Violations of this rule are types in the **typesDeclaredOutOfMainDir** column.
// Typically such type…
//
// •  … is contained in the wrong namespace but its source file is stored in the right directory.
//    In such situation the type should be contained in the namespace corresponding to
//    the parent directory.
//
// •  … is contained in the right namespace but its source file is stored in the wrong directory.
//    In such situation the source file of the type must be moved to the *main directory*.
//
// •  … is declared in multiple source files, stored in different directories.
//    In such situation it is preferable that all source files are stored in a single directory.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 2 minutes plus 5 minutes per type in *typesDeclaredOutOfMainDir*.
//</HowToFix>]]></Query>
    </Group>
    <Group Name=".NET Framework Usage" Active="True" ShownInReport="False">
      <Group Name="System" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Mark ISerializable types with SerializableAttribute</Name>
warnif count > 0
          
from t in Application.Types where 
  t.IsPublic && 
 !t.IsDelegate &&
 !t.IsExceptionClass && // Don't match exceptions, since the Exception class
                        // implements ISerializable, this would generate
                        // too many false positives.
  t.Implement ("System.Runtime.Serialization.ISerializable".AllowNoMatch()) && 
 !t.HasAttribute ("System.SerializableAttribute".AllowNoMatch())

select new {
   t,
   t.NbLinesOfCode,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// To be recognized by the CLR as serializable, 
// types must be marked with the *SerializableAttribute* 
// attribute even if the type uses a custom 
// serialization routine through implementation of 
// the *ISerializable* interface.
//
// This rule matches types that implement *ISerializable* and 
// that are not tagged with *SerializableAttribute*.
//</Description>

//<HowToFix>
// To fix a violation of this rule, tag the matched type
// with *SerializableAttribute* .
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Mark assemblies with CLSCompliant (deprecated)</Name>
warnif count > 0 from a in Application.Assemblies where 
  !a.HasAttribute ("System.CLSCompliantAttribute".AllowNoMatch())
select new {
   a,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule has been deprecated and, as a consequence, it is disabled by default.
// Feel free to re-enable it if it makes sense in your dev environment.
// 
// The *Common Language Specification* (CLS) defines naming restrictions, 
// data types, and rules to which assemblies must conform if they are to 
// be used across programming languages. Good design dictates that all 
// assemblies explicitly indicate CLS compliance with **CLSCompliantAttribute**. 
// If the attribute is not present on an assembly, the assembly is not compliant.
//
// Notice that it is possible for a CLS-compliant assembly to contain types or 
// type members that are not compliant.
//
// This rule matches assemblies that are not tagged with
// **System.CLSCompliantAttribute**.
//</Description>

//<HowToFix>
// To fix a violation of this rule, tag the assembly with *CLSCompliantAttribute*.
//
// Instead of marking the whole assembly as non-compliant, you should determine  
// which type or type members are not compliant and mark these elements as such. 
// If possible, you should provide a CLS-compliant alternative for non-compliant 
// members so that the widest possible audience can access all the functionality 
// of your assembly.
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Mark assemblies with ComVisible (deprecated)</Name>
warnif count > 0 from a in Application.Assemblies where 
  !a.HasAttribute ("System.Runtime.InteropServices.ComVisibleAttribute".AllowNoMatch())
select new {
   a,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule has been deprecated and, as a consequence, it is disabled by default.
// Feel free to re-enable it if it makes sense in your dev environment.
//
// The **ComVisibleAttribute** attribute determines how COM clients access 
// managed code. Good design dictates that assemblies explicitly indicate 
// COM visibility. COM visibility can be set for a whole assembly and then 
// overridden for individual types and type members. If the attribute is not 
// present, the contents of the assembly are visible to COM clients.
//
// This rule matches assemblies that are not tagged with
// **System.Runtime.InteropServices.ComVisibleAttribute**.
//</Description>

//<HowToFix>
// To fix a violation of this rule, tag the assembly with *ComVisibleAttribute*.
//
// If you do not want the assembly to be visible to COM clients, set the
// attribute value to **false**.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Mark attributes with AttributeUsageAttribute</Name>
warnif count > 0
from t in JustMyCode.Types where 
   t.DeriveFrom ("System.Attribute".AllowNoMatch()) &&
  !t.HasAttribute ("System.AttributeUsageAttribute".AllowNoMatch())
select new {
   t,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// When you define a custom attribute, mark it by using **AttributeUsageAttribute**
// to indicate where in the source code the custom attribute can be applied. The 
// meaning and intended usage of an attribute will determine its valid locations 
// in code. For example, you might define an attribute that identifies the person 
// who is responsible for maintaining and enhancing each type in a library, and 
// that responsibility is always assigned at the type level. In this case, compilers 
// should enable the attribute on classes, enumerations, and interfaces, but should 
// not enable it on methods, events, or properties. Organizational policies and 
// procedures would dictate whether the attribute should be enabled on assemblies.
//
// The **System.AttributeTargets** enumeration defines the targets that you can 
// specify for a custom attribute. If you omit *AttributeUsageAttribute*, your 
// custom attribute will be valid for all targets, as defined by the **All** value of 
// *AttributeTargets* enumeration.
//
// This rule matches attribute classes that are not tagged with
// **System.AttributeUsageAttribute**.
//</Description>

//<HowToFix>
// To fix a violation of this rule, specify targets for the attribute by using 
// *AttributeUsageAttribute* with the proper *AttributeTargets* values.
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Remove calls to GC.Collect()</Name>
warnif count > 0 

let gcCollectMethods = ThirdParty.Methods.WithFullNameWildcardMatch(
   "System.GC.Collect(*)").ToHashSet()

from m in Application.Methods.UsingAny(gcCollectMethods)
select new { 
   m, 
   gcCollectMethodCalled = m.MethodsCalled.Intersect(gcCollectMethods),
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// It is preferable to avoid calling **GC.Collect()** 
// explicitly in order to avoid some performance pitfall.
//
// More in information on this here:
// http://blogs.msdn.com/ricom/archive/2004/11/29/271829.aspx
//
// This rule matches application methods that call an
// overload of the method *GC.Collect()*.
//</Description>

//<HowToFix>
// Remove matched calls to *GC.Collect()*.
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Don't call GC.Collect() without calling GC.WaitForPendingFinalizers()</Name>
warnif count > 0 

let gcCollectMethods = ThirdParty.Methods.WithFullNameWildcardMatch(
   "System.GC.Collect(*)").ToHashSet()

from m in Application.Methods.UsingAny(gcCollectMethods) where
  !m.IsUsing ("System.GC.WaitForPendingFinalizers()".AllowNoMatch())
select new { 
   m, 
   gcCollectMethodCalled = m.MethodsCalled.Intersect(gcCollectMethods),
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// It is preferable to avoid calling **GC.Collect()** 
// explicitly in order to avoid some performance 
// pitfall. This situation is checked through the 
// default rules: *Remove calls to GC.Collect()*
//
// But if you wish to call *GC.Collect()* anyway, 
// you must do it this way:
//
//   GC.Collect();
//
//   GC.WaitForPendingFinalizers();
//
//   GC.Collect();
//
// To make sure that finalizer got executed, and 
// object with finalizer got cleaned properly.
//
// This rule matches application methods that call an
// overload of the method *GC.Collect()*, without calling
// *GC.WaitForPendingFinalizers()*.
//</Description>

//<HowToFix>
// To fix a violation of this rule, if you really
// need to call *GC.Collect()*, make sure to call
// *GC.WaitForPendingFinalizers()* properly.
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Enum Storage should be Int32</Name>
warnif count > 0 from f in JustMyCode.Fields where 
   f.ParentType.IsEnumeration &&
   f.Name == @"value__" && 
   f.FieldType != null &&
   f.FieldType.FullName != "System.Int32" &&
  !f.IsThirdParty
select new { 
   f, 
   f.SizeOfInst, 
   f.FieldType,
   Debt = 7.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// An enumeration is a value type that defines a set of related named constants. 
// By default, the **System.Int32** data type is used to store the constant value.
//
// Even though you can change this underlying type, it is not necessary or 
// recommended for most scenarios. Note that *no significant performance gain* is 
// achieved by using a data type that is smaller than *Int32*. If you cannot use 
// the default data type, you should use one of the Common Language System 
// (CLS)-compliant integral types, *Byte*, *Int16*, *Int32*, or *Int64* to make 
// sure that all values of the enumeration can be represented in CLS-compliant 
// programming languages.
//
// This rule matches enumerations whose underlying type used to store
// values is not *System.Int32*.
//</Description>

//<HowToFix>
// To fix a violation of this rule, unless size or compatibility issues exist, 
// use *Int32*. For situations where *Int32* is not large enough to hold the values, 
// use *Int64*. If backward compatibility requires a smaller data type, use 
// *Byte* or *Int16*.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Do not raise too general exception types</Name>
                    
warnif count > 0 

let tooGeneralExceptionTypes = ThirdParty.Types.WithFullNameIn(
   "System.Exception", 
   "System.ApplicationException",
   "System.SystemException")

from m in Application.Methods.ThatCreateAny(tooGeneralExceptionTypes)
// Make sure we don't match constructor of exception types
// that actually instantiate System.Exception.
where !m.IsConstructor || tooGeneralExceptionTypes.All(t => !m.ParentType.DeriveFrom(t))
let exceptionsCreated = tooGeneralExceptionTypes.Where(t => m.IsUsing(t))
select new {
   m,
   exceptionsCreated,
   Debt = (15 + 5*exceptionsCreated.Count()).ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// The following exception types are too general 
// to provide sufficient information to the user: 
//
// • System.Exception
//
// • System.ApplicationException
//
// • System.SystemException
//
// If you throw such a general exception type in a library or framework, 
// it forces consumers to catch all exceptions, 
// including unknown exceptions that they do not know how to handle.
//
// This rule matches methods that create an instance of
// such general exception class.
//</Description>

//<HowToFix>
// To fix a violation of this rule, change the type of the thrown exception 
// to either a more derived type that already exists in the framework, 
// or create your own type that derives from *System.Exception*.
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 15 minutes per method matched, plus 5 minutes per too general 
// exception types instantiated by the method.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Do not raise reserved exception types</Name> 
warnif count > 0 

let reservedExceptions = ThirdParty.Types.WithFullNameIn(   
   "System.NullReferenceException",
   "System.ExecutionEngineException",
   "System.IndexOutOfRangeException",
   "System.OutOfMemoryException",
   "System.StackOverflowException",
   "System.InvalidProgramException",
   "System.AccessViolationException",
   "System.CannotUnloadAppDomainException",
   "System.BadImageFormatException",
   "System.DataMisalignedException")

from m in Application.Methods.ThatCreateAny(reservedExceptions)
let reservedExceptionsCreated = reservedExceptions.Where(t => m.IsUsing(t))
select new { 
   m,
   reservedExceptionsCreated,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// The following exception types are reserved
// and should be thrown only by the Common Language Runtime:
//
// • System.ExecutionEngineException
//
// • System.IndexOutOfRangeException
//
// • System.NullReferenceException
//
// • System.OutOfMemoryException
//
// • System.StackOverflowException
//
// • System.InvalidProgramException
//
// • System.AccessViolationException
//
// • System.CannotUnloadAppDomainException
//
// • System.BadImageFormatException
//
// • System.DataMisalignedException
//
// Do not throw an exception of such reserved type.
//
// This rule matches methods that create an instance of
// such reserved exception class.
//</Description>

//<HowToFix>
// To fix a violation of this rule, change the type of the 
// thrown exception to a specific type that is not one of 
// the reserved types.
//
// Concerning the particular case of a method throwing
// *System.NullReferenceException*, often the fix will be either 
// to throw instead *System.ArgumentNullException*, either to
// use a contract (through MS Code Contracts API or *Debug.Assert()*)
// to signify that a null reference at that point can only be
// the consequence of a bug.
//
// More generally the idea of using a contract instead of throwing
// an exception in case of *corrupted state / bug consequence* detected 
// is a powerful idea. It replaces a behavior (throwing exception)
// with a declarative assertion that basically means: at that point a bug
// somehow provoqued the detected corrupted state and continuing
// any processing from now is potentially harmful. The process should be
// shutdown and the circonstances of the failure should be reported
// as a bug to the product team.
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Use integral or string argument for indexers</Name>
warnif count > 0
from m in Application.Methods where 
  m.IsIndexerGetter && 
 !( (m.Name == @"get_Item(String)") || 
     m.NameLike (@"get_Item\(Int") || 
     m.NameLike (@"get_Item\(Byte") ||
     m.NameLike (@"get_Item\(SByte") )
select new {
   m,
   Debt = 15.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// Indexers, that is, indexed properties, should use *integer* or *string*
// types for the index. These types are typically used for indexing data 
// structures and increase the usability of the library. Use of the *Object*
// type should be restricted to those cases where the specific *integer* or 
// *string* type cannot be specified at design time. If the design requires 
// other types for the index, reconsider whether the type represents a 
// logical data store. If it does not represent a logical data store, 
// use a method.
//
// This rule matches indexer getter methods that whose index type
// is not *string*, *int*, *byte* or *sbyte*.
//</Description>

//<HowToFix>
// To fix a violation of this rule, change the index to an *integer* or *string*
// type, or use a method instead of the indexer.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Uri fields should be of type System.Uri</Name>          
warnif count > 0 from f in Application.Fields where 
  (f.NameLike (@"Uri$") || 
   f.NameLike (@"Url$")) && 
   f.FieldType != null &&
   f.FieldType.FullName != "System.Uri"
select new { 
   f, 
   f.FieldType,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// A field with the name ending with *'Uri'* or *'Url'* is deemed 
// to represent a *Uniform Resource Identifier or Locator*.
// Such field should be of type **System.Uri**.
//
// This rule matches fields with the name ending with *'Uri'* or 
// *'Url'* that are not typed with *System.Uri*.
//</Description>

//<HowToFix>
// Rename the field, or change the field type to *System.Uri*.
//
// By default issues of this rule have an **Low** severity
// because they reflect more an advice than a problem.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types should not extend System.ApplicationException</Name>          
warnif count > 0 from t in Application.Types where
  t.DeriveFrom("System.ApplicationException".AllowNoMatch())
select new {
   t,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// At .NET Framework version 1 time, it was 
// recommended to derive new exceptions from 
// *ApplicationException*. 
//
// The recommendation has changed and new 
// exceptions should derive from **System.Exception**
// or one of its subclasses in the *System* namespace.
//
// This rule matches application exception classes
// that derive from *ApplicationException*.
//</Description>

//<HowToFix>
// Make sure that matched exception types, 
// derive from **System.Exception** or one of its 
// subclasses in the *System* namespace.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[from n in Namespaces
where n.Name ==  "Apache.Ignite.Core.Communication"
from i in n.AllIssues()   // If we call Issues() instead of AllIssue() we only get issues on the namespace
select new { 
   i, 
   Debt = i.Debt, 
   AnnualInterest = i.AnnualInterest,
   BreakingPoint = i.BreakingPoint 
}]]></Query>
      </Group>
      <Group Name="System.Collection" Active="True" ShownInReport="False">
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Collection properties should be read only</Name>
warnif count > 0

// First find collectionTypes 
let collectionInterfaces = ThirdParty.Types.WithFullNameIn(
      "System.Collections.ICollection", 
      "System.Collections.Generic.ICollection<T>")
where collectionInterfaces.Count() > 0
let collectionTypes = Types.ThatImplementAny(collectionInterfaces)
                           .Union(collectionInterfaces)
                           .ToHashSet()

// Then find all property setters that have an associated 
// getter that returns a collection type.
from propGetter in JustMyCode.Methods.Where(
   m => m.IsPropertyGetter && 
        m.ReturnType != null &&
        collectionTypes.Contains(m.ReturnType))

let propSetter = propGetter.ParentType.Methods.WithSimpleName(
      propGetter.SimpleName.Replace("get_","set_")
   ).FirstOrDefault()

where  propSetter != null &&
      !propSetter.IsPrivate &&
      !propSetter.ParentType.IsPrivate && // Ignore setters of private types

       // Ignore properties of serializable types
      !propSetter.ParentType.HasAttribute("System.Runtime.Serialization.DataContractAttribute".AllowNoMatch()) &&
      !propSetter.ParentType.HasAttribute("System.Xml.Serialization.XmlRootAttribute".AllowNoMatch())  

select new { 
   propSetter, 
   CollectionType = propGetter.ReturnType,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// A writable collection property allows a user to replace the collection with 
// a completely different collection. A read-only property stops the collection 
// from being replaced but still allows the individual members to be set. If 
// replacing the collection is a goal, the preferred *design pattern* is to include
// a method to remove all the elements from the collection and a method to 
// re-populate the collection. See the *Clear()* and *AddRange()* methods of the 
// *System.Collections.Generic.List<T>* class for an example of this pattern.
// 
// Both binary and XML serialization support read-only properties that are 
// collections. The *System.Xml.Serialization.XmlSerializer* class has specific 
// requirements for types that implement *ICollection* and *System.Collections.IEnumerable*
// in order to be serializable.
//
// This rule matches property setter methods that assign a collection object.
//</Description>

//<HowToFix>
// To fix a violation of this rule, make the property read-only and, if 
// the design requires it, add methods to clear and re-populate the collection.
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Don't use .NET 1.x HashTable and ArrayList (deprecated)</Name>
warnif count > 0 
let forbiddenTypes = ThirdParty.Types.WithFullNameIn(
   "System.Collections.HashTable", 
   "System.Collections.ArrayList",
   "System.Collections.Queue",
   "System.Collections.Stack",
   "System.Collections.SortedList")
where forbiddenTypes.Count() > 0
from m in Application.Methods.ThatCreateAny(forbiddenTypes)
let forbiddenTypesUsed = m.MethodsCalled.Where(m1 => m1.IsConstructor && forbiddenTypes.Contains(m1.ParentType)).ParentTypes()
select new {
   m,
   forbiddenTypesUsed,
   Debt = 15.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule has been deprecated and, as a consequence, it is disabled by default.
// Feel free to re-enable it if it makes sense in your dev environment.
//
// This rule warns about application methods that use a non-generic 
// collection class, including **ArrayList**, **HashTable**, **Queue**, 
// **Stack** or **SortedList**.
//</Description>

//<HowToFix>
// **List<T>** should be preferred over **ArrayList**.
// It is generic hence you get strongly typed elements.
// Also, it is faster with *T* as a value types since it avoids boxing.
//
// For the same reasons:
//
// • **Dictionary<K,V>** should be prevered over **HashTable**.
//
// • **Queue<T>** should be prevered over **Queue**.
//
// • **Stack<T>** should be prevered over **Stack**.
//
// • **SortedDictionary<K,V>** or **SortedList<K,V>** should be prevered over **SortedList**.
//
// You can be forced to use *non generic* collections
// because you are using third party code that requires 
// working with these classes or because you are 
// coding with .NET 1.x, but nowadays this situation should
// question about using newer updates of .NET.
// .NET 1.x is an immature platform conpared to newer .NET
// updates.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Caution with List.Contains()</Name>

// warnif count > 0  // This query is n ot a rule per default

let containsMethods = ThirdParty.Methods.WithFullNameIn(
   "System.Collections.Generic.List<T>.Contains(T)",
   "System.Collections.Generic.IList<T>.Contains(T)",
   "System.Collections.ArrayList.Contains(Object)")

from m in Application.Methods.UsingAny(containsMethods) 
select new {
   m,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// This code query matches calls to *List<T>.Contains()* method.
//
// The cost of checking if a list contains an object is proportional 
// to the size of the list. In other words it is a *O(N)* operation. 
// For large lists and/or frequent calls to *Contains()*, prefer using  
// the *System.Collections.Generic.HashSet<T>* class 
// where calls to *Contains()* take a constant 
// time (*O(0)* operation).
//
// This code query is not a code rule, because more often than not, 
// calling *O(N) Contains()* is not a mistake. This code query
// aims at pointing out this potential performance pitfall.
//</Description>]]></Query>
        <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Prefer return collection abstraction instead of implementation</Name>

// warnif count > 0  // This query is n ot a rule per default

let implTypes = ThirdParty.Types.WithFullNameIn(
   "System.Collections.Generic.List<T>",
   "System.Collections.Generic.HashSet<T>",
   "System.Collections.Generic.Dictionary<TKey,TValue>")

from m in Application.Methods.WithReturnTypeIn(implTypes) 
select new { 
   m, 
   m.ReturnType,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Low
}

//<Description>
// This code query matches methods that return a 
// collection implementation, such as *List<T>*
// *HashSet<T>* or *Dictionary<TKey,TValue>*.
//
// Most often than not, clients of a method don't 
// need to know the exact implementation of the 
// collection returned. It is preferable to return 
// a collection interface such as *IList<T>*, 
// *ICollection<T>*, *IEnumerable<T>* or
// *IDictionary<TKey,TValue>*.
//
// Using the collection interface instead of the 
// implementation shouldn't applies to all cases, 
// hence this code query is not code rule.
//</Description>]]></Query>
      </Group>
      <Group Name="System.Runtime.InteropServices" Active="True" ShownInReport="False">
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>P/Invokes should be static and not be publicly visible</Name>
warnif count > 0 from m in Application.Methods where
  !m.IsThirdParty &&
  (m.HasAttribute ("System.Runtime.InteropServices.DllImportAttribute".AllowNoMatch())) &&
  ( m.IsPublic || 
   !m.IsStatic)
select new { 
   m, 
   m.Visibility, 
   m.IsStatic,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// Methods that are marked with the **DllImportAttribute** attribute 
// (or methods that are defined by using the **Declare** keyword in Visual Basic) 
// use **Platform Invocation Services** to access unmanaged code.
//
// Such methods should not be exposed. By keeping these methods *private* or *internal*,
// you make sure that your library cannot be used to breach security by allowing 
// callers access to unmanaged APIs that they could not call otherwise.
//
// This rule matches methods tagged with *DllImportAttribute* attribute
// that are declared as *public* or declared as *non-static*.
//</Description>

//<HowToFix>
// To fix a violation of this rule, change the access level of the method
// and/or declare it as static.
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Move P/Invokes to NativeMethods class</Name>
warnif count > 0 from m in Application.Methods where
   m.HasAttribute ("System.Runtime.InteropServices.DllImportAttribute".AllowNoMatch()) &&
   m.ParentType.SimpleName != "NativeMethods"
select new {
   m,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// **Platform Invocation methods**, such as those that are marked by using the 
// **System.Runtime.InteropServices.DllImportAttribute** attribute, or methods 
// that are defined by using the **Declare** keyword in Visual Basic, access 
// unmanaged code. These methods should be in one of the following classes:
//
// • **NativeMethods** - This class does not suppress stack walks for unmanaged 
// code permission. (*System.Security.SuppressUnmanagedCodeSecurityAttribute*
// must not be applied to this class.) This class is for methods that can be 
// used anywhere because a stack walk will be performed.
//
// • **SafeNativeMethods** - This class suppresses stack walks for unmanaged 
// code permission. (*System.Security.SuppressUnmanagedCodeSecurityAttribute*
//is applied to this class.) This class is for methods that are safe for anyone 
// to call. Callers of these methods are not required to perform a full security 
// review to make sure that the usage is secure because the methods are harmless 
// for any caller.
//
// • **UnsafeNativeMethods** - This class suppresses stack walks for unmanaged 
// code permission. (*System.Security.SuppressUnmanagedCodeSecurityAttribute*
// is applied to this class.) This class is for methods that are potentially 
// dangerous. Any caller of these methods must perform a full security review 
// to make sure that the usage is secure because no stack walk will be performed.
//
// These classes are declared as *static internal*. The methods in these 
// classes are *static* and *internal*.
//
// This rule matches *P/Invoke* methods not declared in such *NativeMethods*
// class.
//</Description>

//<HowToFix>
// To fix a violation of this rule, move the method to the appropriate 
// **NativeMethods** class. For most applications, moving P/Invokes to a new 
// class that is named **NativeMethods** is enough.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>NativeMethods class should be static and internal</Name>
warnif count > 0 from t in Application.Types.WithNameIn(
   @"NativeMethods", "SafeNativeMethods", "UnsafeNativeMethods") where
   t.IsPublic || !t.IsStatic
select new { 
   t, 
   t.Visibility, 
   t.IsStatic,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// In the description of the default rule *Move P/Invokes to NativeMethods class*
// it is explained that *NativeMethods* classes that host *P/Invoke* methods,
// should be declared as *static* and *internal*.
//
// This code rule warns about *NativeMethods* classes that are not declared
// *static* and *internal*.
//</Description>

//<HowToFix>
// Matched *NativeMethods* classes must be declared as *static* and *internal*.
//</HowToFix>]]></Query>
      </Group>
      <Group Name="System.Threading" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Don't create threads explicitly</Name>
warnif count > 0 from m in Application.Methods where 
  m.CreateA ("System.Threading.Thread".AllowNoMatch())
select new {
   m,
   Debt = 60.ToMinutes().ToDebt(),
   Severity = Severity.Critical
}

//<Description>
// This code rule warns about methods that create *threads* explicitly
// by creating an instance of the class *System.Threading.Thread*.
//
// Prefer using the thread pool instead of creating manually your 
// own threads. Threads are costly objects. They take approximately 
// 200,000 cycles to create and about 100,000 cycles to destroy.  
// By default they reserve 1 Mega Bytes of virtual memory for its 
// stack and use 2,000-8,000 cycles for each context switch.
//
// As a consequence, it is preferable to let the thread pool 
// recycle threads.
//</Description>

//<HowToFix>
// Instead of creating explicitly threads, use the **Task Parralel 
// Library** *(TPL)* that relies on the CLR thread pool.
// 
// Introduction to TPL: https://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx
//
// TPL and the CLR v4 thread pool:
// http://www.danielmoth.com/Blog/New-And-Improved-CLR-4-Thread-Pool-Engine.aspx
//
// By default issues of this rule have a **Critical** severity
// because creating threads can have severe consequences. 
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Don't use dangerous threading methods</Name>
warnif count > 0 

let wrongMethods = ThirdParty.Methods.WithFullNameIn(

  "System.Threading.Thread.Abort()",
  "System.Threading.Thread.Abort(Object)",
     
  "System.Threading.Thread.Sleep(Int32)",

  "System.Threading.Thread.Suspend()",
  "System.Threading.Thread.Resume()")

from m in Application.Methods.UsingAny(wrongMethods)
select new { 
   m, 
   suppressCallsTo = m.MethodsCalled.Intersect(wrongMethods),
   Debt = 40.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns about using the methods
// *Abort()*, *Sleep()*, *Suspend()* or *Resume()*
// declared by the *Thread* class.
//
// • Usage of *Thread.Abort()* is dangerous.
// More information on this here:
// http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
//
// • Usage of *Thread.Sleep()* is a sign of 
// flawed design. More information on this here:
// http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx
//
// • *Suspend()* and *Resume()* are dangerous threading methods, marked as obsolete.
// More information on workaround here:
// http://stackoverflow.com/questions/382173/what-are-alternative-ways-to-suspend-and-resume-a-thread  
//</Description>

//<HowToFix>
// Suppress calls to *Thread* methods exposed in the 
// *suppressCallsTo* column in the rule result.
//
// Use instead facilities offered by the **Task Parralel 
// Library** *(TPL)* :
// https://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Monitor TryEnter/Exit must be both called within the same method</Name>
warnif count > 0 

let enterMethods = ThirdParty.Methods.WithFullNameWildcardMatchIn(
   "System.Threading.Monitor.Enter(*",
   "System.Threading.Monitor.TryEnter(*")

from m in Application.Methods.UsingAny(enterMethods) 
where
    !m.IsUsing ("System.Threading.Monitor.Exit(Object)".AllowNoMatch())
select new { 
   m, 
   enterMethodsCalled = m.MethodsCalled.Intersect(enterMethods),
   Debt = 20.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns when **System.Threading.Monitor** *Enter()* 
// (or *TryEnter()*) and *Exit() methods are not called within 
// the same method.
//
// Doing so makes the code *less readable*, because it gets harder
// to locate when **critical sections** begin and end.
//
// Also, you expose yourself to complex and error-prone scenarios.
//</Description>

//<HowToFix>
// Refactor matched methods to make sure that *Monitor critical 
// sections* begin and end within the same method. Basics scenarios 
// can be handled through the C# **lock** keyword. Using explicitly 
// the class *Monitor* should be left for advanced situations, 
// that require calls to methods like *Wait()* and *Pulse()*.
//
// More information on using the *Monitor* class can be found here:
// http://www.codeproject.com/Articles/13453/Practical-NET-and-C-Chapter
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>ReaderWriterLock AcquireLock/ReleaseLock must be both called within the same method</Name>
warnif count > 0 

let acquireLockMethods = ThirdParty.Methods.WithFullNameWildcardMatch(
    "System.Threading.ReaderWriterLock.Acquire*Lock(*")

let releaseLockMethods = ThirdParty.Methods.WithFullNameWildcardMatch(
    "System.Threading.ReaderWriterLock.Release*Lock(*")

from m in Application.Methods.UsingAny(acquireLockMethods)
  .Except(Application.Methods.UsingAny(releaseLockMethods))
select new { 
   m, 
   acquireLockMethods = m.MethodsCalled.Intersect(acquireLockMethods),
   Debt = 20.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns when **System.Threading.ReaderWriterLock** 
// acquire and release, reader or writer locks methods are not called 
// within the same method.
//
// Doing so makes the code *less readable*, because it gets harder
// to locate when **critical sections** begin and end.
//
// Also, you expose yourself to complex and error-prone scenarios.
//</Description>

//<HowToFix>
// Refactor matched methods to make sure that *ReaderWriterLock 
// read or write critical sections* begin and end within the 
// same method.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Don't tag instance fields with ThreadStaticAttribute</Name>
warnif count > 0
from f in Application.Fields 
where !f.IsStatic && 
       f.HasAttribute ("System.ThreadStaticAttribute".AllowNoMatch())
select new {
   f,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule warns when the attribute **System.ThreadStaticAttribute**
// is tagging *instance* fields. As explained in documentation, this attribute
// is designed to tag only *static* fields.
// https://msdn.microsoft.com/en-us/library/system.threadstaticattribute
//</Description>

//<HowToFix>
// Refactor the code to make sure that all fields tagged with 
// *ThreadStaticAttribute* are *static*.
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Method non-synchronized that read mutable states</Name>
from m in Application.Methods where 
 (m.ReadsMutableObjectState || m.ReadsMutableTypeState) && 
 !m.IsUsing ("System.Threading.Monitor".AllowNoMatch()) && 
 !m.IsUsing ("System.Threading.ReaderWriterLock".AllowNoMatch())
select new {
   m, 
   mutableFieldsUsed = m.FieldsUsed.Where(f => !f.IsImmutable)
}

//<Description>
// Mutable object states are instance fields that 
// can be modified through the lifetime of the object.
//
// Mutable type states are static fields that can be 
// modified through the lifetime of the program.
//
// This query lists methods that read mutable state 
// without synchronizing access. In the case of 
// multi-threaded program, doing so can lead to 
// state corruption.
//
// This code query is not a code rule because more often
// than not, a match of this query is not an issue.
//</Description>]]></Query>
      </Group>
      <Group Name="System.Xml" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Method should not return concrete XmlNode</Name>
warnif count > 0 

let concreteXmlTypes = ThirdParty.Types.ThatDeriveFromAny(
                       ThirdParty.Types.WithFullName("System.Xml.XmlNode"))

from m in Application.Methods.WithReturnTypeIn(concreteXmlTypes)
select new { 
   m, 
   m.ReturnType,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule warns about method whose return type is
// **System.Xml.XmlNode** or any type derived from *XmlNode*.
//
// *XmlNode* implements the interface **System.Xml.Xpath.IXPathNavigable**.
// In most situation, returning this interface instead of the concrete
// type is a better *design* choice that will abstract client code
// from implementation details.
//</Description>

//<HowToFix>
// To fix a violation of this rule, change the concrete returned type 
// to the suggested interface *IXPathNavigable* and refactor clients
// code if possible.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types should not extend System.Xml.XmlDocument</Name>
warnif count > 0 from t in Application.Types where
   t.DeriveFrom("System.Xml.XmlDocument".AllowNoMatch())
select new {
   t,
   Debt = 20.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule warns aboud subclasses of **System.Xml.XmlDocument**.
//
// Do not create a subclass of *XmlDocument* if you want to 
// create an XML view of an underlying object model or data source.
//</Description>

//<HowToFix>
// Instead of subclassing *XmlDocument*, you can use the interface 
// **System.Xml.XPath.IXPathNavigable** implemented by the class 
// *XmlDocument*.
//
// An alternative of using *XmlDocument*, is to use 
// **System.Xml.Linq.XDocument**, aka **LINQ2XML**. 
// More information on this can be found here: 
// http://stackoverflow.com/questions/1542073/xdocument-or-xmldocument
//</HowToFix>]]></Query>
      </Group>
      <Group Name="System.Globalization" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Float and Date Parsing must be culture aware</Name>
warnif count > 0 

let cultureUnawareMethods =
  (from m in ThirdParty.Types.WithFullNameIn( 
             "System.DateTime", 
             "System.Single", 
             "System.Double",
             "System.Decimal").ChildMethods()
   where  m.NbParameters > 0 &&
        (m.SimpleName.EqualsAny(
           "Parse", "TryParse", "ToString")) &&
        !m.Name.Contains("IFormatProvider")
   select m).ToHashSet()

from m in Application.Methods.UsingAny(cultureUnawareMethods)
let cultureUnawareMethodsCalled = m.MethodsCalled.Intersect(cultureUnawareMethods)
select new { 
   m, 
   shouldntCall = cultureUnawareMethodsCalled,
   Debt =    (5 + 3*cultureUnawareMethodsCalled.Count()).ToMinutes().ToDebt(),
   Severity = 5*cultureUnawareMethodsCalled.Count().ToMinutes().ToAnnualInterest()
}

//<Description>
// Globalization is the design and development of applications that support 
// localized user interfaces and regional data for users in multiple cultures.
//
// This rule warns about the usage of *non-globalized overloads* of
// the methods **Parse()**, **TryParse()** and **ToString()**, 
// of the types **DateTime**, **float**, **double** and **decimal**.
// This is the symptom that your application is *at least partially* 
// not globalized.
//
// *Non-globalized overloads* of these methods are the overloads
// that don't take a parameter of type **IFormatProvider**.
//</Description>

//<HowToFix>
// Globalize your applicaton and make sure to use the globalized overloads 
// of these methods. In the column **MethodsCallingMe** of this rule result
// are listed the methods of your application that call the 
// *non-globalized overloads*.
//
// More information on **Creating Globally Aware Applications** here:
// https://msdn.microsoft.com/en-us/library/cc853414(VS.95).aspx
//
// The estimated Debt, which means the effort to fix such issue,
// is equal to 5 minutes per application method calling at least one
// non-culture aware method called, plus 3 minutes per non-culture aware 
// method called.
//</HowToFix>]]></Query>
      </Group>
      <Group Name="System.Reflection" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Mark assemblies with assembly version</Name>
warnif count > 0 from a in Application.Assemblies where 
  !a.HasAttribute ("System.Reflection.AssemblyVersionAttribute".AllowNoMatch())
select new {
   a,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// The identity of an assembly is composed of the following information:
//
// • Assembly name
//
// • Version number
//
// • Culture
//
// • Public key (for strong-named assemblies).
//
// The .NET Framework uses the version number to uniquely identify an 
// assembly, and to bind to types in strong-named assemblies. The 
// version number is used together with version and publisher policy. 
// By default, applications run only with the assembly version with 
// which they were built.
//
// This rule matches assemblies that are not tagged with
// **System.Reflection.AssemblyVersionAttribute**.
//</Description>

//<HowToFix>
// To fix a violation of this rule, add a version number to the assembly 
// by using the *System.Reflection.AssemblyVersionAttribute* attribute.
//</HowToFix>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Assemblies should have the same version</Name>
warnif count > 0
let versionsLookup = Application.Assemblies.ToLookup(a => a.Version, a=> a)
let mostRepresentedVersion = versionsLookup.OrderByDescending(v => v.Count()).First().Key
from v in versionsLookup
where v.Key != mostRepresentedVersion 
from a in v.ToArray()
select new { 
   a , 
   version = v.Key, 
   mostRepresentedVersion,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule reports application assemblies that have a version different 
// than the version shared by most of application assemblies.
// 
// Before fixing these issues, double check if there is a valid reason
// for dealing with more than one assembly version number.
// Typically this happens when the analyzed code base is made of assemblies 
// that are not *compiled, developed or deployed* together.
//</Description>

//<HowToFix>
// If all assemblies of your application should have the same version number,
// just use the attribute **System.Reflection.AssemblyVersion** in a source 
// file shared by the assemblies.
//
// Typically this source file is generated by a dedicated *MSBuild* task 
// like this one http://www.msbuildextensionpack.com/help/4.0.5.0/html/d6c3b5e8-00d4-c826-1a73-3cfe637f3827.htm.
//
// Here you can find interesting assemblies versioning advices.
// http://stackoverflow.com/a/3905443/27194
//
// By default issues of this rule have a severity set to **major** since
// unproper assemblies versioning can lead to complicated deployment problem.
//</HowToFix>]]></Query>
      </Group>
      <Group Name="Microsoft.Contracts" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Public methods returning a reference needs a contract to ensure that a non-null reference is returned</Name>
warnif count > 0
let ensureMethods = Application.Methods.WithFullName(
   "System.Diagnostics.Contracts.__ContractsRuntime.Ensures(Boolean,String,String)")

from ensureMethod in ensureMethods
from m in ensureMethod.ParentAssembly.ChildMethods where 
  m.IsPubliclyVisible &&
 !m.IsAbstract &&
  m.ReturnType != null &&
  // Identify that the return type is a reference type
  (m.ReturnType.IsClass || m.ReturnType.IsInterface) &&
 !m.IsUsing(ensureMethod) &&

  // Don't match method not implemented yet!
 !m.CreateA("System.NotImplementedException".AllowNoMatch())

select new { 
   m, 
   ReturnTypeReference = m.ReturnType,
   Debt = (5+3*m.MethodsCallingMe.Count()).ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// **Code Contracts** are useful to decrease ambiguity between callers and callees.
// Not ensuring that a reference returned by a method is *non-null* leaves ambiguity 
// for the caller. This rule matches methods returning an instance of a reference type 
// (class or interface) that doesn't use a **Contract.Ensure()** method.
//
// *Contract.Ensure()* is defined in the **Microsoft Code Contracts for .NET** 
// library, and is typically used to write a code contract on returned reference:
// *Contract.Ensures(Contract.Result<ReturnType>() != null, "returned reference is not null");*
// https://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970
//</Description>

//<HowToFix>
// Use *Microsoft Code Contracts for .NET* on the public surface of your API,
// to remove most ambiguity presented to your client. Most of such ambiguities
// are about *null* or *not null* references.
//
// Don't use *null* reference if you need to define a method that might not 
// return a result. Use instead the **TryXXX()** pattern exposed for example 
// in the *System.Int32.TryParse()* method.
//
// The estimated Debt, which means the effort to fix such issue, is equal
// to 5 minutes per public application method that might return a null reference 
// plus 3 minutes per method calling such method.
//</HowToFix>]]></Query>
      </Group>
    </Group>
    <Group Name="Defining JustMyCode" Active="True" ShownInReport="False">
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Assemblies from JustMyCode</Name>
notmycode
from a in Application.Assemblies where 
// Assemblies generated for Xsl IL compilation for example are tagged with this attribute
a.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch())
select a

//<Description>
// This code query is prefixed with **notmycode**.
// This means that all application assemblies matched by this 
// code query are removed from the *code base view* **JustMyCode.Assemblies**.
// It also means that all *namespaces*, *types*, *methods* and 
// *fields* contained in a matched assembly are removed from
// the code base view *JustMyCode*.
// The code base view *JustMyCode* is used by most default code queries 
// and rules.
//
// So far this query only matches application assemblies tagged
// with *System.CodeDom.Compiler.GeneratedCodeAttribute*.
// Make sure to make this query richer to discard your generated 
// assemblies from the NDepend rules results.
//
// *notmycode* queries are executed before running others
// queries and rules. Also modifying a *notmycode* query
// provokes re-run of queries and rules that rely 
// on the *JustMyCode* code base view.
//
// Several *notmycode* queries can be written to match *assemblies*,
// in which case this results in cumulative effect.
//
// Online documentation:
// http://www.ndepend.com/docs/cqlinq-syntax#NotMyCode
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Namespaces from JustMyCode</Name>             
notmycode

// First gather assemblies written with VB.NET
let vbnetAssemblies = Application.Assemblies.Where(
   a => a.SourceDecls.Any(decl => decl.SourceFile.FileNameExtension.ToLower() == ".vb"))

// Then find the My namespace and its child namespaces.
let vbnetMyNamespaces = vbnetAssemblies.ChildNamespaces().Where(
   n => n.SimpleName == "My" ||
   n.ParentNamespaces.Any(nParent => nParent.SimpleName == "My"))

from n in vbnetMyNamespaces
select n

//<Description>
// This code query is prefixed with **notmycode**.
// This means that all application namespaces matched by this 
// code query are removed from the *code base view* **JustMyCode.Namespaces**.
// It also means that all *types*, *methods* and *fields* contained in a 
// matched namespace are removed from the code base view *JustMyCode*.
// The code base view *JustMyCode* is used by most default code queries 
// and rules.
//
// So far this query matches the **My** namespaces generated
// by the VB.NET compiler.
//
// *notmycode* queries are executed before running others
// queries and rules. Also modifying a *notmycode* query
// provokes re-run of queries and rules that rely 
// on the *JustMyCode* code base view.
//
// Several *notmycode* queries can be written to match *namespaces*,
// in which case this results in cumulative effect.
//
// Online documentation:
// http://www.ndepend.com/docs/cqlinq-syntax#NotMyCode
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Types from JustMyCode</Name>             
notmycode

// Define some sets to quickly test EntityFramework generated types
let efContexts = Application.Types.Where(t => 
  t.DeriveFrom("System.Data.Entity.DbContext".AllowNoMatch()) &&
  t.SourceDecls.Count(sd => sd.SourceFile.FileName.ToLower().EndsWithAny(".context.cs", ".context.vb")) == 1).ToHashSet()
let efEntities = Application.Types.UsedByAny(efContexts).ToHashSet()
let efMigrations = Application.Types.Where(t => t.DeriveFrom("System.Data.Entity.Migrations.DbMigration".AllowNoMatch())).ToHashSet()

from t in Application.Types where

  // Don't consider anonymous types as JustMyCode  
  // C# and VB.NET anonymous types generated by the compiler satisfies these conditions
  (t.IsGeneratedByCompiler && 
   t.ParentNamespace.Name.Length == 0 &&
   t.SimpleNameLike("AnonymousType")) ||

  // Resources, Settings, or typed DataSet generated types for example, are tagged with this attribute
  t.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) ||

  // This attribute identifies a type or member that is not part of the user code for an application.
  t.HasAttribute ("System.Diagnostics.DebuggerNonUserCodeAttribute".AllowNoMatch()) ||

  // Delegate types are always generated
  t.IsDelegate ||

  // Discard ASP.NET page types generated by aspnet_compiler.exe
  // See: http://www.ndepend.com/FAQ.aspx#ASPNET
  t.ParentNamespace.Name.EqualsAny("ASP", "__ASP") ||

  // Discard Xamarin form generated types that contain the method LoadDataTemplate()
 (t.IsNested && 
  t.SimpleName.StartsWith("<InitializeComponent>") && 
  t.Methods.Count(m => m.SimpleName == "LoadDataTemplate") == 1 &&
  t.ParentAssembly.AssembliesUsed.Count(a => a.Name.StartsWith("Xamarin")) > 0)  ||

  // Discard Xamarin Resource types
 (t.IsNested && 
  t.ParentType != null && 
  t.ParentType.Name == "Resource" && 
  t.ParentAssembly.AssembliesUsed.Count(a => a.Name.StartsWith("Xamarin")) > 0) ||

  // Discard Entity Framework generated DB context types and entities types used by DB context types!
  efContexts.Contains(t) ||
  efEntities.Contains(t) ||
  efMigrations.Contains(t) ||

  // Discard types generated for code contract
  t.FullName.StartsWith("System.Diagnostics.Contracts.__ContractsRuntime") ||
  t.FullName == "System.Diagnostics.Contracts.RuntimeContractsAttribute" ||

  // Discard all types declared in a folder path containing the word "generated"
  (t.SourceFileDeclAvailable &&
   t.SourceDecls.All(s => s.SourceFile.FilePath.ParentDirectoryPath.ToString().ToLower().Contains("generated")))

select t

//<Description>
// This code query is prefixed with **notmycode**.
// This means that all application types matched by this 
// code query are removed from the *code base view* **JustMyCode.Types**.
// It also means that all *methods* and *fields* contained in a 
// matched type are removed from the code base view *JustMyCode*.
// The code base view *JustMyCode* is used by most default code queries 
// and rules.
//
// So far this query matches several well-identified generated
// types, like the ones tagged with *System.CodeDom.Compiler.GeneratedCodeAttribute*.
// Make sure to make this query richer to discard your generated 
// types from the NDepend rules results.
//
// *notmycode* queries are executed before running others
// queries and rules. Also modifying a *notmycode* query
// provokes re-run of queries and rules that rely 
// on the *JustMyCode* code base view.
//
// Several *notmycode* queries can be written to match *types*,
// in which case this results in cumulative effect.
//
// Online documentation:
// http://www.ndepend.com/docs/cqlinq-syntax#NotMyCode
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated and designer Methods from JustMyCode</Name>
notmycode 

//
// First define source files paths to discard
//
from a in Application.Assemblies 
where a.SourceFileDeclAvailable 
let asmSourceFilesPaths = a.SourceDecls.Select(s => s.SourceFile.FilePath)

let sourceFilesPathsToDiscard = (
    from filePath in asmSourceFilesPaths 
    let filePathLower= filePath.ToString().ToLower()
    where     
      filePathLower.EndsWithAny(
        ".g.cs",        // Popular pattern to name generated files.
        ".g.vb",
        ".generated.cs",
        ".generated.vb",
        ".xaml",        // notmycode WPF xaml code
        ".designer.cs", // notmycode C# Windows Forms designer code
        ".designer.vb") // notmycode VB.NET Windows Forms designer code
       ||
       // notmycode methods in source files in a directory containing generated
       filePathLower.Contains("generated")
  select filePath
).ToHashSet() 
  
//
// Second: discard methods in sourceFilesPathsToDiscard 
//
from m in a.ChildMethods
where (m.SourceFileDeclAvailable && 
       sourceFilesPathsToDiscard.Contains(m.SourceDecls.First().SourceFile.FilePath)) ||
      // Generated methods might be tagged with this attribute
      m.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) ||

      // This attributes identifies a type or member that is not part of the user code for an application.
      m.HasAttribute ("System.Diagnostics.DebuggerNonUserCodeAttribute".AllowNoMatch())

select new { m, m.NbLinesOfCode }

//<Description>
// This code query is prefixed with **notmycode**.
// This means that all application methods matched by this 
// code query are removed from the *code base view* **JustMyCode.Methods**.
// The code base view *JustMyCode* is used by most default code queries 
// and rules.
//
// So far this query matches several well-identified generated
// methods, like the ones tagged with *System.CodeDom.Compiler.GeneratedCodeAttribute*,
// or the ones declared in a source file suffixed with *.designer.cs*. 
// Make sure to make this query richer to discard your generated 
// methods from the NDepend rules results.
//
// *notmycode* queries are executed before running others
// queries and rules. Also modifying a *notmycode* query
// provokes re-run of queries and rules that rely 
// on the *JustMyCode* code base view.
//
// Several *notmycode* queries can be written to match *methods*,
// in which case this results in cumulative effect.
//
// Online documentation:
// http://www.ndepend.com/docs/cqlinq-syntax#NotMyCode
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Discard generated Fields from JustMyCode</Name>
notmycode
from f in Application.Fields where 
  f.HasAttribute ("System.CodeDom.Compiler.GeneratedCodeAttribute".AllowNoMatch()) ||

  // Eliminate "components" generated in Windows Form Control context
  f.Name == "components" && f.ParentType.DeriveFrom("System.Windows.Forms.Control".AllowNoMatch())
select f

//<Description>
// This code query is prefixed with **notmycode**.
// This means that all application fields matched by this 
// code query are removed from the *code base view* **JustMyCode.Fields**.
// The code base view *JustMyCode* is used by most default code queries 
// and rules.
//
// So far this query only matches application fields tagged
// with *System.CodeDom.Compiler.GeneratedCodeAttribute*, and 
// *Windows Form* generated fields named *components*.
// Make sure to make this query richer to discard your generated 
// fields from the NDepend rules results.
//
// *notmycode* queries are executed before running others
// queries and rules. Also modifying a *notmycode* query
// provokes re-run of queries and rules that rely 
// on the *JustMyCode* code base view.
//
// Several *notmycode* queries can be written to match *fields*,
// in which case this results in cumulative effect.
//
// Online documentation:
// http://www.ndepend.com/docs/cqlinq-syntax#NotMyCode
//</Description>]]></Query>
      <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>JustMyCode code elements</Name>
from elem in JustMyCode.CodeElements
select new { 
  elem,
  loc = elem.IsMethod? elem.AsMethod.NbLinesOfCode : null
}

//<Description>
// This code query enumerates all
// *assemblies*, *namespaces*, *types*, *methods* and *fields*
// in your application, that are considered as being your code.
//
// This means concretely that the *ICodeBaseView* **JustMyCode**
// only shows these code elements. This code base view is used by 
// many default code rule to avoid being warned on code elements 
// that you don't consider as your code - typically the code 
// elements generated by a tool.
//
// These code elements are the ones that are not matched 
// by any quere prefixed with  **notmycode**.
//</Description>]]></Query>
      <Query Active="False" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>NotMyCode code elements</Name>
from elem in Application.CodeElements.Where(element => !JustMyCode.Contains(element))
select new { 
  elem,
  loc = elem.IsMethod? elem.AsMethod.NbLinesOfCode : null
}

//<Description>
// This code query enumerates all
// *assemblies*, *namespaces*, *types*, *methods* and *fields*
// in your application, that are considered as not being your code.
//
// This means concretely that the *ICodeBaseView* **JustMyCode**
// hide these code elements. This code base view is used by 
// many default code rules to avoid being warned on code elements 
// that you don't consider as your code - typically the code 
// elements generated by a tool.
//
// These code elements are the ones matched by queries prefixed with 
// **notmycode**.
//</Description>]]></Query>
    </Group>
    <Group Name="Trend Metrics" Active="True" ShownInReport="False">
      <Group Name="Issues" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# New Issues since Baseline" Unit="issues"/>
from issue in Issues 
where issue.WasAdded()
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Issues Fixed since Baseline" Unit="issues"/>
from issue in Issues 
where issue.WasFixed()
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Issues Worsened since Baseline" Unit="issues"/>
from issue in Issues 
where !issue.WasAdded() && 
      (issue.DebtDiff() > Debt.Zero || issue.AnnualInterestDiff() > AnnualInterest.Zero)
select new { 
   issue, 
   issue.Debt, debtDiff = issue.DebtDiff(), 
   issue.AnnualInterest, annualInterestDiff = issue.AnnualInterestDiff(),
   issue.Severity 
}

//<Description>
// An issue is considered worsened if its *debt* increased since the baseline.
//
// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
//</Description>
]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Issues with severity Blocker" Unit="issues"/>
from issue in Issues 
where issue.Severity == Severity.Blocker
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }

//<Description>
// An issue with the severity **Blocker** cannot move to production, it must be fixed.
//
// The severity of an issue is inferred from the issue *annual interest*
// and thresholds defined in the NDepend Project Properties > Issue and Debt.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Issues with severity Critical" Unit="issues"/>
from issue in Issues 
where issue.Severity == Severity.Critical
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }

//<Description>
// An issue with a severity level **Critical** shouldn't move to production. 
// It still can for business imperative needs purposes, but at worth it must be fixed during the next iterations. 
//
// The severity of an issue is inferred from the issue *annual interest*
// and thresholds defined in the NDepend Project Properties > Issue and Debt.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Issues with severity High" Unit="issues"/>
from issue in Issues 
where issue.Severity == Severity.High
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }

//<Description>
// An issue with a severity level **High** should be fixed quickly, but can wait until the next scheduled interval.
//
// The severity of an issue is inferred from the issue *annual interest*
// and thresholds defined in the NDepend Project Properties > issue and Debt.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Issues with severity Medium" Unit="issues"/>
from issue in Issues 
where issue.Severity == Severity.Medium
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }

//<Description>
// An issue with a severity level **Medium** is a warning that if not fixed, won't have a significant impact on development.
//
// The severity of an issue is inferred from the issue *annual interest*
// and thresholds defined in the NDepend Project Properties > issue and Debt.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Issues with severity Low" Unit="issues"/>
from issue in Issues 
where issue.Severity == Severity.Low
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }

//<Description>
// The severity level **Low** is used by issues that have a zero, or close to zero, 
// value for **Annual Interest**.
//
// Issues with a **Low** or **Medium** severity level represents small improvements, 
// ways to make the code looks more elegant.
//
// The **Broken Window Theory** https://en.wikipedia.org/wiki/Broken_windows_theory states that:
//
// *"Consider a building with a few broken windows. 
// If the windows are not repaired, the tendency is for vandals to break a few more windows. 
// Eventually, they may even break into the building, and if it's unoccupied, perhaps become 
// squatters or light fires inside."*
//

// Issues with a *Low* or *Medium* severity level represents the *broken windows* of a code base.
// If they are not fixed, the tendency is for developers to not care for living 
// in an elegant code, which will result in extra-maintenance-cost in the long term.
//
// The severity of an issue is inferred from the issue *annual interest*
// and thresholds defined in the NDepend Project Properties > issue and Debt.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Blocker/Critical/High Issues" Unit="issues"/>
from issue in Issues 
where issue.Severity.EqualsAny(Severity.Blocker, Severity.Critical, Severity.High)
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }

//<Description>
// The number of issues with a severity Blocker, Critical or High.
//
// An issue with the severity **Blocker** cannot move to production, it must be fixed.
//
// An issue with a severity level **Critical** shouldn't move to production. 
// It still can for business imperative needs purposes, but at worth it must be fixed during the next iterations. 
//
// An issue with a severity level **High** should be fixed quickly, but can wait until the next scheduled interval.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Issues" Unit="issues"/>
from issue in Issues 
select new { issue, issue.Debt, issue.AnnualInterest, issue.Severity }

//<Description>
// The number of issues no matter the issue severity.
//</Description>]]></Query>
      </Group>
      <Group Name="Rules" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Rules" Unit="rules"/>
from rule in Rules
select new { 
   rule, 
   issues = rule.Issues(), 
   debt = rule.Debt(), 
   annualInterest = rule.AnnualInterest(),
   maxSeverity = rule.IsViolated() ? (Severity?)rule.Issues().Max(i => i.Severity) : null
}

//<Description>
// This trend metric counts the number of active rules.
// This count includes violated and not violated rules.
// This count includes critical and non critical rules.
//
// When no baseline is available, rules that rely on diff are not counted.
// If you observe that this count slightly decreases with no apparent reason,
// the reason is certainly that rules that rely on diff are not counted
// because the baseline is not defined.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Rules Violated" Unit="rules"/>
from rule in Rules
where rule.IsViolated()
select new { 
   rule, 
   issues = rule.Issues(), 
   debt = rule.Debt(), 
   annualInterest = rule.AnnualInterest(),
   maxSeverity = rule.Issues().Max(i => i.Severity)
}

//<Description>
// This trend metric counts the number of active rules that are violated.
// This count includes critical and non critical rules.
//
// When no baseline is available, rules that rely on diff are not counted.
// If you observe that this count slightly decreases with no apparent reason,
// the reason is certainly that rules that rely on diff are not counted
// because the baseline is not defined.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Critical Rules Violated" Unit="rules"/>
from rule in Rules
where rule.IsViolated() && rule.IsCritical
select new { 
   rule, 
   issues = rule.Issues(), 
   debt = rule.Debt(), 
   annualInterest = rule.AnnualInterest(),
   maxSeverity = rule.Issues().Max(i => i.Severity)
}

//<Description>
// This trend metric counts the number of critical active rules that are violated.
//
// The concept of critical rule is useful to pinpoint certain rules that should not be violated.
//
// When no baseline is available, rules that rely on diff are not counted.
// If you observe that this count slightly decreases with no apparent reason,
// the reason is certainly that rules that rely on diff are not counted
// because the baseline is not defined.
//</Description>]]></Query>
      </Group>
      <Group Name="Quality Gates" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Quality Gates" Unit="quality gates"/>
from qualityGate in QualityGates
select new { 
   qualityGate , 
   qualityGate.ValueString,
   qualityGate.Status, 
}

//<Description>
// This trend metric counts the number of active quality gates,
// no matter the gate status (Pass, Warn, Fail).
//
// When no baseline is available, quality gates that rely on diff are not counted.
// If you observe that this count slightly decreases with no apparent reason,
// the reason is certainly that quality gates that rely on diff are not counted
// because the baseline is not defined.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Quality Gates Warn" Unit="quality gates"/>
from qualityGate in QualityGates
where qualityGate.Warn
select new { 
   qualityGate , 
   qualityGate.ValueString, 
}

//<Description>
// This trend metric counts the number of active quality gates that warns.
//
// When no baseline is available, quality gates that rely on diff are not counted.
// If you observe that this count slightly decreases with no apparent reason,
// the reason is certainly that quality gates that rely on diff are not counted
// because the baseline is not defined.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Quality Gates Fail" Unit="quality gates"/>
from qualityGate in QualityGates
where qualityGate.Fail
select new { 
   qualityGate , 
   qualityGate.ValueString, 
}

//<Description>
// This trend metric counts the number of active quality gates that fails.
//
// When no baseline is available, quality gates that rely on diff are not counted.
// If you observe that this count slightly decreases with no apparent reason,
// the reason is certainly that quality gates that rely on diff are not counted
// because the baseline is not defined.
//</Description>]]></Query>
      </Group>
      <Group Name="Debt" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Percentage Debt (Metric)" Unit="%" />
let timeToDev = codeBase.EffortToDevelop()
let debt = Issues.Sum(i => i.Debt)
select 100d * debt.ToManDay() / timeToDev.ToManDay()

// <Description>
// This Trend Metric name is suffixed with (Metric)
// to avoid query name collision with the Quality Gate with same name.
//
// Infer a percentage from:
//
// • the estimated total time to develop the code base
//
// • and the the estimated total time to fix all issues (the Debt).
//
// Estimated total time to develop the code base is inferred from 
// # lines of code of the code base and from the 
// *Estimated number of man-day to develop 1000 logicial lines of code*
// setting found in NDepend Project Properties > Issue and Debt.
//
// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
// </Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Debt (Metric)" Unit="man-days" />
Issues.Sum(i => i.Debt).ToManDay()

//<Description>
// This Trend Metric name is suffixed with (Metric)
// to avoid query name collision with the Quality Gate with same name.
//
// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="New Debt since Baseline (Metric)" Unit="man-days" />
let debt = Issues.Sum(i => i.Debt)
let debtInBaseline = IssuesInBaseline.Sum(i => i.Debt)
select (debt - debtInBaseline).ToManDay()

//<Description>
// This Trend Metric name is suffixed with (Metric)
// to avoid query name collision with the Quality Gate with same name.
//
// Debt added (or fixed if negative) since baseline.
//
// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Annual Interest (Metric)" Unit="man-days" />
Issues.Sum(i => i.AnnualInterest).ToManDay()

//<Description>
// This Trend Metric name is suffixed with (Metric)
// to avoid query name collision with the Quality Gate with same name.
//
// Annual Interest documentation: http://www.ndepend.com/docs/technical-debt#AnnualInterest
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="New Annual Interest since Baseline (Metric)" Unit="man-days" />
let ai = Issues.Sum(i => i.AnnualInterest)
let aiInBaseline = IssuesInBaseline.Sum(i => i.AnnualInterest)
select (ai - aiInBaseline).ToManDay()

//<Description>
// This Trend Metric name is suffixed with (Metric)
// to avoid query name collision with the Quality Gate with same name.
//
// Annual Interest added (or fixed if negative) since baseline.
//
// Annual Interest documentation: http://www.ndepend.com/docs/technical-debt#AnnualInterest
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Breaking Point" Unit="years"/>
(Issues.Sum(i =>i.Debt).BreakingPoint(Issues.Sum(i =>i.AnnualInterest))).TotalYears()

// <Description>
// The **breaking point** of a set of issues is the **debt** divided by the **annual interest**.
//
// The *debt* is the estimated cost-to-fix the issues.
//
// The *annual interest* is the estimated cost-to-**not**-fix the issues, per year.
//
// Hence the *breaking point* is the point in time from now, when not fixing the issues cost as much as fixing the issue.
//
// Breaking Point documentation: http://www.ndepend.com/docs/technical-debt#BreakingPoint
// </Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Breaking Point of Blocker / Critical / High Issues" Unit="years"/>
let issues = Issues.Where(i => i.Severity.EqualsAny(Severity.Blocker, Severity.Critical, Severity.High))
select (issues.Sum(i =>i.Debt).BreakingPoint(issues.Sum(i =>i.AnnualInterest))).TotalYears()

// <Description>
// The **breaking point** of a set of issues is the **debt** divided by the **annual interest**.
//
// The *debt* is the estimated cost-to-fix the issues.
//
// The *annual interest* is the estimated cost-to-**not**-fix the issues, per year.
//
// Hence the *breaking point* is the point in time from now, when not fixing the issues cost as much as fixing the issue.
//
// Breaking Point documentation: http://www.ndepend.com/docs/technical-debt#BreakingPoint
// </Description>]]></Query>
      </Group>
      <Group Name="Code Size" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code" Unit="LoC" />
codeBase.NbLinesOfCode]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code (JustMyCode)" Unit="LoC" />
JustMyCode.Methods.Sum(m => m.NbLinesOfCode)

// JustMyCode is defined by code queries prefixed with 'notmycode' 
// in the group 'Defining JustMyCode'.
]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code (NotMyCode)" Unit="LoC" />
Application.Methods.Except(JustMyCode.Methods).Sum(m => m.NbLinesOfCode)

// JustMyCode is defined by code queries prefixed with 'notmycode' 
// in the group 'Defining JustMyCode'.
]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code Added since the Baseline" Unit="LoC" />  
from a in Application.Assemblies
let nbLocAdded = !a.IsPresentInBothBuilds()
                 ? a.NbLinesOfCode
                 : (a.NbLinesOfCode != null && a.OlderVersion().NbLinesOfCode != null)
               ? a.NbLinesOfCode - (int)a.OlderVersion().NbLinesOfCode 
                   : 0
select (double?)nbLocAdded


// A value is computed by this Trend Metric query
// only if a Baseline for Comparison is provided.
// See Project Properties > Analysis > Baseline for Comparison
]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Source Files" Unit="Source Files" />
Application.Assemblies.SelectMany(
  a => a.SourceDecls.Select(sd => sd.SourceFile.FilePathString.ToLower()))
.Distinct()
.Count()

//<Description>
// This trend metric counts the number of source files.
//
// If a value 0 is obtained, it means that at analysis time,
// assemblies PDB files were not available.
// http://www.ndepend.com/docs/ndepend-analysis-inputs-explanation
//
// So far source files cannot be matched by a code query.
// However editing the query "Application Types" and then
// *Group by source file declarations* will list source files
// with types source declarations.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# IL Instructions" Unit="IL Instructions" />
codeBase.NbILInstructions
]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# IL Instructions (NotMyCode)" Unit="IL Instructions" />
Application.Methods.Except(JustMyCode.Methods).Sum(m => m.NbILInstructions)

// JustMyCode is defined by code queries prefixed with 'notmycode' 
// in the group 'Defining JustMyCode'.
]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Comments" Unit="Lines" />  
codeBase.NbLinesOfComment

//<Description>
// This trend metric returns the number of lines of comment
// counted in application source files.
//
// So far commenting information is only extracted from C# source code
// and VB.NET support is planned.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Percentage of Comments" Unit="%" />  
codeBase.PercentageComment

//<Description>
// This trend metric returns the percentage of comment
// compared to the number of **logical**lines of code.
//
// So far commenting information is only extracted from C# source code
// and VB.NET support is planned.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Assemblies" Unit="Assemblies" />
from a in Application.Assemblies
select new {
   a,
   Debt = a.AllDebt(),
   Issues = a.AllIssues()
}

//<Description>
// This trend metric query counts all application assemblies.
// For each assembly it shows the estimated **all** technical-debt and **all** issues.
// **All** means debt and issues of the assembly and of its child namespaces, types and members.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Namespaces" Unit="Namespaces" />
from n in Application.Namespaces
select new {
   n,
   Debt = n.AllDebt(),
   Issues = n.AllIssues()
}

//<Description>
// This trend metric query counts all application namespaces.
// For each namespace it shows the estimated **all** technical-debt and **all** issues.
// **All** means debt and issues of the namespace and of its child types and members.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Types" Unit="Types" />
from t in Application.Types.Where(t => !t.IsGeneratedByCompiler)
select new {
   t,
   Debt = t.AllDebt(),
   Issues = t.AllIssues()
}

//<Description>
// This trend metric query counts all application types non-generated by compiler.
// For each type it shows the estimated **all** technical-debt and **all** issues.
// **All** means debt and issues of the type and of its child members.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Public Types" Unit="Types" />
Application.Types.Where(t => t.IsPubliclyVisible && !t.IsGeneratedByCompiler)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Classes" Unit="Types" />
Application.Types.Where(t => t.IsClass && !t.IsGeneratedByCompiler)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Abstract Classes" Unit="Types" />
Application.Types.Where(t => t.IsClass && t.IsAbstract && !t.IsGeneratedByCompiler)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Interfaces" Unit="Types" />
Application.Types.Where(t => t.IsInterface)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Structures" Unit="Types" />
Application.Types.Where(t => t.IsStructure && !t.IsGeneratedByCompiler)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Methods" Unit="Methods" />
from m in Application.Methods.Where(m => !m.IsGeneratedByCompiler)
select new {
   m,
   Debt = m.Debt(),
   Issues = m.Issues()
}

//<Description>
// This trend metric query counts all application methods non-generated by compiler.
// For each method it shows the estimated technical-debt and the issues.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Abstract Methods" Unit="Methods" />
Application.Methods.Where(m => m.IsAbstract)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Concrete Methods" Unit="Methods" />
Application.Methods.Where(m => !m.IsAbstract && !m.IsGeneratedByCompiler)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Fields" Unit="Fields" />
from f in Application.Fields.Where(f => 
   !f.IsEnumValue && 
   !f.ParentType.IsEnumeration &&
   !f.IsGeneratedByCompiler && 
   !f.IsLiteral)
select new {
   f,
   Debt = f.AllDebt(),
   Issues = f.AllIssues()
}

//<Description>
// This trend metric query counts all application fields non-generated by compiler
// that are not enumeration values nor constant values.
// For each field it shows the estimated technical-debt and the issues.
//</Description>]]></Query>
      </Group>
      <Group Name="Maximum and Average" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max # Lines of Code for Methods (JustMyCode)" Unit="LoC" />
JustMyCode.Methods
          .Max(m => m.NbLinesOfCode)

// Here is the code query to get the (JustMyCode) method with largest # Lines of Code
// JustMyCode.Methods.OrderByDescending(m => m.NbLinesOfCode).Take(1).Select(m => new {m, m.NbLinesOfCode})]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Lines of Code for Methods" Unit="LoC" />
Application.Methods.Where(m => m.NbLinesOfCode > 0)
                   .Average(m => m.NbLinesOfCode)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Lines of Code for Methods with at least 3 Lines of Code" Unit="LoC" />
Application.Methods.Where(m => m.NbLinesOfCode >= 3)
                   .Average(m => m.NbLinesOfCode)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max # Lines of Code for Types (JustMyCode)" Unit="LoC" />
JustMyCode.Types
          .Max(t => t.NbLinesOfCode)

// Here is the code query to get the (JustMyCode) type with largest # Lines of Code
// JustMyCode.Types.OrderByDescending(t => t.NbLinesOfCode).Take(1).Select(t => new {t, t.NbLinesOfCode})]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Lines of Code for Types" Unit="LoC" />
Application.Types.Where(t => t.NbLinesOfCode > 0)
                 .Average(t => t.NbLinesOfCode)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max Cyclomatic Complexity for Methods" Unit="Paths" />
Application.Methods
           .Max(m => m.CyclomaticComplexity)

// Here is the code query to get the most complex method, according to Cyclomatic Complexity
// Application.Methods.OrderByDescending(m => m.CyclomaticComplexity).Take(1).Select(m => new {m, m.CyclomaticComplexity})]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average Cyclomatic Complexity for Methods" Unit="Paths" />
Application.Methods.Where(m => m.NbLinesOfCode> 0)
                   .Average(m => m.CyclomaticComplexity)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max IL Cyclomatic Complexity for Methods" Unit="Paths" />
Application.Methods
           .Max(m => m.ILCyclomaticComplexity)

// Here is the code query to get the most complex method, according to Cyclomatic Complexity computed from IL code.
// Application.Methods.OrderByDescending(m => m.ILCyclomaticComplexity).Take(1).Select(m => new {m, m.CyclomaticComplexity})]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average IL Cyclomatic Complexity for Methods" Unit="Paths" />
Application.Methods.Where(m => m.NbILInstructions> 0)
                   .Average(m => m.ILCyclomaticComplexity)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max IL Nesting Depth for Methods" Unit="Scopes" />
Application.Methods
           .Max(m => m.ILNestingDepth)

// Here is the code query to get the method with higher ILNestingDepth.
// Application.Methods.OrderByDescending(m => m.ILNestingDepth).Take(1).Select(m => new {m, m.ILNestingDepth})]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average IL Nesting Depth for Methods" Unit="Scopes" />
Application.Methods.Where(m => m.NbILInstructions> 0)
                   .Average(m => m.ILNestingDepth)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max # of Methods for Types" Unit="Methods" />
Application.Types
           .Max(t => t.NbMethods) 

// Here is the code query to get the (JustMyCode) type with largest # of Methods
// JustMyCode.Types.OrderByDescending(t => t.NbMethods).Take(1).Select(t => new {t, t.Methods})]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Methods for Types" Unit="Methods" />
Application.Types.Average(t => t.NbMethods)]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max # of Methods for Interfaces" Unit="Methods" />
Application.Types.Where(t => t.IsInterface)
                 .Max(t => t.NbMethods)

// Here is the code query to get the (JustMyCode) type with largest # of Methods
// JustMyCode.Types.OrderByDescending(t => t.NbMethods).Take(1).Select(t => new {t, t.Methods})]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average # Methods for Interfaces" Unit="Methods" />
JustMyCode.Types.Where(t => t.IsInterface)
                .Average(t => t.NbMethods)]]></Query>
      </Group>
      <Group Name="Coverage" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Percentage Code Coverage" Unit="%" />
codeBase.PercentageCoverage]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code Covered" Unit="LoC" />
codeBase.NbLinesOfCodeCovered]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code Not Covered" Unit="LoC" />
codeBase.NbLinesOfCodeNotCovered]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code Uncoverable" Unit="LoC" />
(codeBase.NbLinesOfCode - codeBase.NbLinesOfCodeCovered - codeBase.NbLinesOfCodeNotCovered).ToNullableDouble()

//<Description>
// **Lines of Code Uncoverable** are lines of code in methods tagged with the *Uncoverable attribute*
// or methods in types or assemblies tagged with the *Uncoverable attribute*.
//
// The *Uncoverable attribute* is defined in the:
//   NDepend Project Properties > Analysis > Code Coverage > Un-Coverable attributes.
//
// These methods can be listed with the code query:
//   *from m in Methods where !m.CoverageDataAvailable && m.NbLinesOfCode > 0 select new { m, m.NbLinesOfCode }*
//
// If coverage data imported at analysis time is not *in-sync* with the analyzed code base,
// this code query will also list methods not defined in the coverage data imported.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code in Types 100% Covered" Unit="LoC" />
Application.Types.Where(t => t.PercentageCoverage == 100)
                 .Sum(t => t.NbLinesOfCodeCovered)

//<Description>
// A line of code covered by tests is *even more valuable* if it is in a type 100% covered by test.
//
// Covering 90% of a class is not enough.
//
// • It means that this 10% uncovered code is hard-to-test,
//
// • which means that this code is not well-designed,
//
// • which means that it is error-prone.
//
// Better test error-prone code, isn't it?
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Lines of Code in Methods 100% Covered" Unit="LoC" />
Application.Methods.Where(m => m.PercentageCoverage == 100)
                   .Sum(m => m.NbLinesOfCodeCovered)

//<Description>
// The same remark than in the Trend Metric **# Lines of Code in Types 100% Covered**
// applies for method 100% covered.
//
// A line of code covered by tests is *even more valuable* if it is in a method 100% covered by test.
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Max C.R.A.P Score" />

(from m in JustMyCode.Methods

// Don't match too short methods
where m.NbLinesOfCode > 10

let CC = m.CyclomaticComplexity
let uncov = (100 - m.PercentageCoverage) / 100f
let CRAP = (CC * CC * uncov * uncov * uncov) + CC
where CRAP != null && CRAP > 30 select CRAP)
.Max(CRAP => CRAP)

//<Description>
// **Change Risk Analyzer and Predictor** (i.e. CRAP) is a code metric
// that helps in pinpointing overly complex and untested code.
// Is has been first defined here: 
// http://www.artima.com/weblogs/viewpost.jsp?thread=215899
//
// The Formula is:  **CRAP(m) = CC(m)^2 * (1 – cov(m)/100)^3 + CC(m)**
//
// • where *CC(m)* is the *cyclomatic complexity* of the method *m*
//
// • and *cov(m)* is the *percentage coverage* by tests of the method *m*
//
// Matched methods cumulates two highly *error prone* code smells:
//
// • A complex method, difficult to develop and maintain.
//
// • Non 100% covered code, difficult to refactor without any regression bug.
//
// The higher the CRAP score, the more painful to maintain and error prone is the method.
//
// An arbitrary threshold of 30 is fixed for this code rule as suggested by inventors.
//
// Notice that no amount of testing will keep methods with a Cyclomatic Complexity
// higher than 30, out of CRAP territory.
//
// Notice that CRAP score is not computed for too short methods
// with less than 10 lines of code.
//
// To list methods with higher C.R.A.P scores, please refer to the default rule:
//   *Test and Code Coverage* > *C.R.A.P method code metric*
//</Description>]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="Average C.R.A.P Score" />

(from m in JustMyCode.Methods

// Don't match too short methods
where m.NbLinesOfCode > 10

let CC = m.CyclomaticComplexity
let uncov = (100 - m.PercentageCoverage) / 100f
let CRAP = (CC * CC * uncov * uncov * uncov) + CC
where CRAP != null && CRAP > 30 select CRAP)
.Average(CRAP => CRAP)

//<Description>
// **Change Risk Analyzer and Predictor** (i.e. CRAP) is a code metric
// that helps in pinpointing overly complex and untested code.
// Is has been first defined here: 
// http://www.artima.com/weblogs/viewpost.jsp?thread=215899
//
// The Formula is:  **CRAP(m) = CC(m)^2 * (1 – cov(m)/100)^3 + CC(m)**
//
// • where *CC(m)* is the *cyclomatic complexity* of the method *m*
//
// • and *cov(m)* is the *percentage coverage* by tests of the method *m*
//
// Matched methods cumulates two highly *error prone* code smells:
//
// • A complex method, difficult to develop and maintain.
//
// • Non 100% covered code, difficult to refactor without any regression bug.
//
// The higher the CRAP score, the more painful to maintain and error prone is the method.
//
// An arbitrary threshold of 30 is fixed for this code rule as suggested by inventors.
//
// Notice that no amount of testing will keep methods with a Cyclomatic Complexity
// higher than 30, out of CRAP territory.
//
// Notice that CRAP score is not computed for too short methods
// with less than 10 lines of code.
//
// To list methods with higher C.R.A.P scores, please refer to the default rule:
//   *Test and Code Coverage* > *C.R.A.P method code metric*
//</Description>]]></Query>
      </Group>
      <Group Name="Third-Party Usage" Active="True" ShownInReport="False">
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Assemblies Used" Unit="Assemblies" />
from a in ThirdParty.Assemblies
select new { a, a.AssembliesUsingMe }]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Namespaces Used" Unit="Namespaces" />
from n in ThirdParty.Namespaces
select new { n, n.NamespacesUsingMe }]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Types Used" Unit="Types" />
from t in ThirdParty.Types
select new { t, t.TypesUsingMe }]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Methods Used" Unit="Methods" />
from m in ThirdParty.Methods
select new { m, m.MethodsCallingMe }]]></Query>
        <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Fields Used" Unit="Fields" />
from f in ThirdParty.Fields
where !f.ParentType.IsEnumeration
select new { f, f.MethodsUsingMe }]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <TrendMetric Name="# Third-Party Code Elements Used" Unit="Code Elements" />
from elem in ThirdParty.CodeElements
where !(elem.IsField && elem.AsField.ParentType.IsEnumeration)
let users = elem.IsMethod ?    elem.AsMethod.MethodsCallingMe.Cast<ICodeElement>() :
            elem.IsField  ?    elem.AsField.MethodsUsingMe.Cast<ICodeElement>() :
            elem.IsType ?      elem.AsType.TypesUsingMe.Cast<ICodeElement>() :
            elem.IsNamespace ? elem.AsNamespace.NamespacesUsingMe.Cast<ICodeElement>() :
                               elem.AsAssembly.AssembliesUsingMe.Cast<ICodeElement>()
select new { elem, users }
]]></Query>
      </Group>
    </Group>
    <Group Name="Code Diff Summary" Active="True" ShownInReport="True">
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New assemblies</Name>
from a in Application.Assemblies where a.WasAdded()
select new { a, a.NbLinesOfCode }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *assemblies* that have been added since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Assemblies removed</Name>
from a in codeBase.OlderVersion().Application.Assemblies where a.WasRemoved()
select new { a, a.NbLinesOfCode }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *assemblies* that have been removed since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Assemblies where code was changed</Name>
from a in Application.Assemblies where a.CodeWasChanged()
select new { 
   a, 
   a.NbLinesOfCode, 
   oldNbLinesOfCode = a.OlderVersion().NbLinesOfCode.GetValueOrDefault() ,
   delta = (int) a.NbLinesOfCode.GetValueOrDefault() - a.OlderVersion().NbLinesOfCode.GetValueOrDefault() 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *assemblies* in which, code has been changed since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New namespaces</Name>
from n in Application.Namespaces where 
 !n.ParentAssembly.WasAdded() &&
  n.WasAdded()
select new { n, n.NbLinesOfCode }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *namespaces* that have been added since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Namespaces removed</Name>
from n in codeBase.OlderVersion().Application.Namespaces where 
 !n.ParentAssembly.WasRemoved() &&
  n.WasRemoved()
select new { n, n.NbLinesOfCode }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *namespaces* that have been removed since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Namespaces where code was changed</Name>
from n in Application.Namespaces where n.CodeWasChanged()
select new { 
   n, 
   n.NbLinesOfCode, 
   oldNbLinesOfCode = n.OlderVersion().NbLinesOfCode.GetValueOrDefault() ,
   delta = (int) n.NbLinesOfCode.GetValueOrDefault() - n.OlderVersion().NbLinesOfCode.GetValueOrDefault() 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *namespaces* in which, code has been changed since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New types</Name>
from t in Application.Types where 
 !t.ParentNamespace.WasAdded() &&
  t.WasAdded() &&
 !t.IsGeneratedByCompiler
select new { t, t.NbLinesOfCode }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *types* that have been added since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types removed</Name>
from t in codeBase.OlderVersion().Application.Types where 
 !t.ParentNamespace.WasRemoved() &&
  t.WasRemoved() &&
 !t.IsGeneratedByCompiler
select new { t, t.NbLinesOfCode }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *types* that have been removed since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types where code was changed</Name>

from t in Application.Types where t.CodeWasChanged() 
//select new { t, t.NbLinesOfCode }
select new { 
   t, 
   t.NbLinesOfCode, 
   oldNbLinesOfCode = t.OlderVersion().NbLinesOfCode ,
   delta = (int?) t.NbLinesOfCode - t.OlderVersion().NbLinesOfCode 
} 
//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *types* in which, code has been changed since the *baseline*.
//
// To visualize changes in code, right-click a matched type and select:
//
// • Compare older and newer versions of source file
//
// • Compare older and newer versions disassembled with Reflector
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Heuristic to find types moved from one namespace or assembly to another</Name>
let typesRemoved = codeBase.OlderVersion().Types.Where(t => t.WasRemoved())
let typesAdded = Types.Where(t => t.WasAdded())

from tMoved in typesAdded.Join(
   typesRemoved,
   t => t.Name,
   t => t.Name,
   (tNewer, tOlder) => new { tNewer, 
                             OlderParentNamespace = tOlder.ParentNamespace,
                             OlderParentAssembly = tOlder.ParentAssembly  } ) 
select tMoved

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *types* moved from one namespace or assembly to another.
// The heuristic implemented consists in making a **join LINQ query** on
// type name (without namespace prefix), applied to the two sets of types *added* 
// and types *removed*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types directly using one or several types changed</Name>
let typesChanged = Application.Types.Where(t => t.CodeWasChanged()).ToHashSet()

from t in JustMyCode.Types.UsingAny(typesChanged) where
  !t.CodeWasChanged() && 
  !t.WasAdded()
let typesChangedUsed = t.TypesUsed.Intersect(typesChanged) 
select new { t, typesChangedUsed }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists types *unchanged* since the *baseline*
// but that use directly some *types* where code has been changed 
// since the *baseline*.
//
// For such matched type, the code hasen't been changed, but still the overall
// behavior might have been changed.
//
// The query result includes types changed directly used,
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types indirectly using one or several types changed</Name>
let typesChanged = Application.Types.Where(t => t.CodeWasChanged()).ToHashSet()

// 'depth' represents a code metric defined on types using
// directly or indirectly any type where code was changed.
let depth = JustMyCode.Types.DepthOfIsUsingAny(typesChanged) 

from t in depth.DefinitionDomain where
  !t.CodeWasChanged() && 
  !t.WasAdded()

let typesChangedDirectlyUsed = t.TypesUsed.Intersect(typesChanged) 
let depthOfUsingTypesChanged = depth[t]
orderby depthOfUsingTypesChanged 

select new { 
   t, 
   depthOfUsingTypesChanged, 
   typesChangedDirectlyUsed 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists types *unchanged* since the *baseline*
// but that **use directly or indirectly** some *types* where 
// code has been changed since the *baseline*.
//
// For such matched type, the code hasen't been changed, but still the overall
// behavior might have been changed.
// 
// The query result includes types changed directly used, and the **depth of usage**
// of types indirectly used, *depth of usage* as defined in the documentation of
// *DepthOfIsUsingAny()* NDepend API method:
// http://www.ndepend.com/api/webframe.html?NDepend.API~NDepend.CodeModel.ExtensionMethodsSequenceUsage~DepthOfIsUsingAny.html
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New methods</Name>
from m in Application.Methods where 
 !m.ParentType.WasAdded() &&
  m.WasAdded() &&
 !m.IsGeneratedByCompiler
select new { m, m.NbLinesOfCode }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *methods* that have been added since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods removed</Name>
from m in codeBase.OlderVersion().Application.Methods where 
 !m.ParentType.WasRemoved() &&
  m.WasRemoved() &&
 !m.IsGeneratedByCompiler
select new { m, m.NbLinesOfCode }

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *methods* that have been removed since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods where code was changed</Name>
from m in Application.Methods where m.CodeWasChanged()
select new { 
   m, 
   m.NbLinesOfCode, 
   oldNbLinesOfCode = m.OlderVersion().NbLinesOfCode ,
   delta = (int?) m.NbLinesOfCode - m.OlderVersion().NbLinesOfCode 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *methods* in which, code has been changed since the *baseline*.
//
// To visualize changes in code, right-click a matched method and select:
//
// • Compare older and newer versions of source file
//
// • Compare older and newer versions disassembled with Reflector
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods directly calling one or several methods changed</Name>
let methodsChanged = Application.Methods.Where(m => m.CodeWasChanged()).ToHashSet()

from m in JustMyCode.Methods.UsingAny(methodsChanged ) where
  !m.CodeWasChanged() && 
  !m.WasAdded()
let methodsChangedCalled = m.MethodsCalled.Intersect(methodsChanged) 
select new { 
   m, 
   methodsChangedCalled 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists methods *unchanged* since the *baseline*
// but that call directly some *methods* where code has been changed 
// since the *baseline*.
//
// For such matched method, the code hasen't been changed, but still the overall
// behavior might have been changed.
//
// The query result includes methods changed directly used,
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods indirectly calling one or several methods changed</Name>
let methodsChanged = Application.Methods.Where(m => m.CodeWasChanged()).ToHashSet()

// 'depth' represents a code metric defined on methods using
// directly or indirectly any method where code was changed.
let depth = JustMyCode.Methods.DepthOfIsUsingAny(methodsChanged) 

from m in depth.DefinitionDomain where
  !m.CodeWasChanged() && 
  !m.WasAdded()

let methodsChangedDirectlyUsed = m.MethodsCalled.Intersect(methodsChanged) 
let depthOfUsingMethodsChanged = depth[m]
orderby depthOfUsingMethodsChanged 

select new { 
   m, 
   depthOfUsingMethodsChanged, 
   methodsChangedDirectlyUsed 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists methods *unchanged* since the *baseline*
// but that **use directly or indirectly** some *methods* where 
// code has been changed since the *baseline*.
//
// For such matched method, the code hasen't been changed, but still the overall
// behavior might have been changed.
// 
// The query result includes methods changed directly used, and the **depth of usage**
// of methods indirectly used, *depth of usage* as defined in the documentation of
// *DepthOfIsUsingAny()* NDepend API method:
// http://www.ndepend.com/api/webframe.html?NDepend.API~NDepend.CodeModel.ExtensionMethodsSequenceUsage~DepthOfIsUsingAny.html
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New fields</Name>
from f in Application.Fields where 
 !f.ParentType.WasAdded() &&
  f.WasAdded() &&
 !f.IsGeneratedByCompiler
select f

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *fields* that have been added since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Fields removed</Name>
from f in codeBase.OlderVersion().Application.Fields where 
 !f.ParentType.WasRemoved() &&
  f.WasRemoved() &&
 !f.IsGeneratedByCompiler
select f

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *fields* that have been removed since the *baseline*.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third party types that were not used and that are now used</Name>
from t in ThirdParty.Types where t.IsUsedRecently()
select new { 
   t, 
   t.Methods, 
   t.Fields, 
   t.TypesUsingMe 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *types* defined in **third-party assemblies**, that were not 
// used at *baseline* time, and that are now used.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third party types that were used and that are not used anymore</Name>
from t in codeBase.OlderVersion().Types where t.IsNotUsedAnymore()
select new { 
   t, 
   t.Methods, 
   t.Fields, 
   TypesThatUsedMe = t.TypesUsingMe 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *types* defined in **third-party assemblies**, that were  
// used at *baseline* time, and that are not used anymore.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third party methods that were not used and that are now used</Name>
from m in ThirdParty.Methods where 
  m.IsUsedRecently() &&
 !m.ParentType.IsUsedRecently()
select new { 
   m, 
   m.MethodsCallingMe
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *methods* defined in **third-party assemblies**, that were not 
// used at *baseline* time, and that are now used.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third party methods that were used and that are not used anymore</Name>
from m in codeBase.OlderVersion().Methods where 
  m.IsNotUsedAnymore() &&
 !m.ParentType.IsNotUsedAnymore()
select new { 
   m, 
   MethodsThatCalledMe = m.MethodsCallingMe
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *methods* defined in **third-party assemblies**, that were  
// used at *baseline* time, and that are not used anymore.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third party fields that were not used and that are now used</Name>
from f in ThirdParty.Fields where 
  f.IsUsedRecently() &&
 !f.ParentType.IsUsedRecently()
select new { 
   f, 
   f.MethodsUsingMe 
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *fields* defined in **third-party assemblies**, that were not 
// used at *baseline* time, and that are now used.
//</Description>]]></Query>
      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Third party fields that were used and that are not used anymore</Name>
from f in codeBase.OlderVersion().Fields where 
  f.IsNotUsedAnymore() &&
 !f.ParentType.IsNotUsedAnymore()
select new {
   f, 
   MethodsThatUsedMe = f.MethodsUsingMe
}

//<Description>
// This query is executed only if a *baseline for comparison* is defined (*diff mode*).
//
// This code query lists *fields* defined in **third-party assemblies**, that were  
// used at *baseline* time, and that are not used anymore.
//</Description>]]></Query>
    </Group>
    <Group Name="Statistics" Active="False" ShownInReport="False">
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used types (Rank)</Name>
(from t in Application.Types 
 where !t.IsGeneratedByCompiler
 orderby t.Rank descending
 select new { t, t.Rank, t.TypesUsingMe }).Take(100)

//<Description>
// **TypeRank** values are computed by applying 
// the **Google PageRank** algorithm on the 
// graph of types' dependencies. Types with 
// high *Rank* are the most used ones. Not necessarily
// the ones with the most users types, but the ones
// used by many types, themselves having a lot of 
// types users.
//
// See the definition of the TypeRank metric here: 
// http://www.ndepend.com/docs/code-metrics#TypeRank
//
// This code query lists the 100 application types 
// with the higher rank.
//
// The main consequence of being used a lot for a 
// type is that each change (both *syntax change* 
// and *behavior change*) will result in potentially
// a lot of **pain** since most types clients will be 
// **impacted**.
//
// Hence it is preferable that types with higher 
// *TypeRank*, are **interfaces**, that are typically  
// less subject changes.
//
// Also interfaces avoid clients relying on  
// implementations details. Hence, when the behavior of 
// classes implementing an interface changes, this 
// shouldn't impact clients of the interface.
// This is *in essence* the 
// **Liskov Substitution Principle**.
// http://en.wikipedia.org/wiki/Liskov_substitution_principle
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used methods (Rank)</Name>
(from m in Application.Methods 
 where !m.IsGeneratedByCompiler
 orderby m.Rank descending
 select new { m, m.Rank, m.MethodsCallingMe }).Take(100)

//<Description>
// **MethodRank** values are computed by applying 
// the **Google PageRank** algorithm on the 
// graph of methods' dependencies. Methods with 
// high *Rank* are the most used ones. Not necessarily
// the ones with the most callers methods, but the ones
// called by many methods, themselves having a lot 
// of callers.
//
// See the definition of the MethodRank metric here: 
// http://www.ndepend.com/docs/code-metrics#MethodRank
//
// This code query lists the 100 application methods 
// with the higher rank.
//
// The main consequence of being used a lot for a 
// method is that each change (both *signature change* 
// and *behavior change*) will result in potentially
// a lot of **pain** since most methods callers will be 
// **impacted**.
//
// Hence it is preferable that methods with highest 
// *MethodRank*, are **abstract methods**, that are 
// typically less subject to signature changes.
//
// Also abstract methods avoid callers relying on  
// implementations details. Hence, when the code
// of a method implementing an abstract method changes, 
// this shouldn't impact callers of the abstract method.
// This is *in essence* the 
// **Liskov Substitution Principle**.
// http://en.wikipedia.org/wiki/Liskov_substitution_principle
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used assemblies (#AssembliesUsingMe)</Name>
(from a in Assemblies orderby a.AssembliesUsingMe.Count() descending
 select new { a, a.AssembliesUsingMe }).Take(100)
 
//<Description>
// This code query lists the 100 *application* and *third-party* 
// assemblies, with the higher number of assemblies users.  
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used namespaces (#NamespacesUsingMe )</Name>
(from n in Namespaces orderby n.NbNamespacesUsingMe descending
 select new { n, n.NamespacesUsingMe }).Take(100)
 
//<Description>
// This code query lists the 100 *application* and *third-party* 
// namespaces, with the higher number of namespaces users.  
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used types (#TypesUsingMe )</Name>
(from t in Types orderby t.NbTypesUsingMe descending
 where !t.IsGeneratedByCompiler
 select new { t, t.TypesUsingMe }).Take(100)
 
//<Description>
// This code query lists the 100 *application* and *third-party* 
// types, with the higher number of types users.  
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Most used methods (#MethodsCallingMe )</Name>
(from m in Methods orderby m.NbMethodsCallingMe 
 where !m.IsGeneratedByCompiler
 select new { m, m.MethodsCallingMe }).Take(100)

//<Description>
// This code query lists the 100 *application* and *third-party* 
// methods, with the higher number of methods callers.  
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Namespaces that use many other namespaces (#NamespacesUsed )</Name>
(from n in Application.Namespaces orderby n.NbNamespacesUsed descending
 select new { n, n.NamespacesUsed }).Take(100)
 
//<Description>
// This code query lists the 100 *application* namespaces 
// with the higher number of namespaces used.  
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types that use many other types (#TypesUsed )</Name>
(from t in Application.Types orderby t.NbTypesUsed descending
 select new { t, t.TypesUsed, isMyCode = JustMyCode.Contains(t) }).Take(100)
 
//<Description>
// This code query lists the 100 *application* types 
// with the higher number of types used.  
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Methods that use many other methods (#MethodsCalled )</Name>
(from m in Application.Methods orderby m.NbMethodsCalled descending
 select new { m, m.MethodsCalled, isMyCode = JustMyCode.Contains(m) }).Take(100)

//<Description>
// This code query lists the 100 *application* methods 
// with the higher number of methods called.  
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level assemblies (Level)</Name>
from a in Application.Assemblies orderby a.Level descending
select new { a, a.Level }

//<Description>
// This code query lists assemblies ordered by **Level** values.
// See the definition of the *AssemblyLevel* metric here:
// http://www.ndepend.com/docs/code-metrics#Level
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level namespaces (Level)</Name>
from n in Application.Namespaces orderby n.Level descending
select new { n, n.Level }

//<Description>
// This code query lists namespaces ordered by **Level** values.
// See the definition of the *NamespaceLevel* metric here:
// http://www.ndepend.com/docs/code-metrics#Level
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level types (Level)</Name>
from t in Application.Types orderby t.Level descending
select new { t, t.Level }

//<Description>
// This code query lists types ordered by **Level** values.
// See the definition of the *TypeLevel* metric here:
// http://www.ndepend.com/docs/code-metrics#Level
//</Description>]]></Query>
      <Query Active="True" DisplayList="False" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>High-level to low-level methods (Level)</Name>
from m in Application.Methods orderby m.Level descending
select new { m, m.Level }

//<Description>
// This code query lists methods ordered by **Level** values.
// See the definition of the *MethodLevel* metric here:
// http://www.ndepend.com/docs/code-metrics#Level
//</Description>]]></Query>
    </Group>
    <Group Name="Samples of Custom rules" Active="False" ShownInReport="False">
      <Group Name="Check Architecture" Active="False" ShownInReport="False">
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that the assembly Asm1 is not using the assembly Asm2</Name>
warnif count > 0 from a in Application.Assemblies where 
  a.IsUsing ("Asm2".AllowNoMatch().MatchAssembly()) &&
  (a.Name == @"Asm1")
select new {
   a,
   Debt = 30.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to be warned if a particular assembly is using
// another particular assembly.
//
// Such rule can be generated for assemblies **A** and **B**:
//
// • by right clicking the cell in the *Dependency Matrix* 
// with **B** in row and **A** in column,
//
// • or by right-clicking the concerned arrow in the *Dependency 
// Graph* from **A** to **B**,
//
// and in both cases, click the menu
// **Generate a code rule that warns if this dependency exists**
//
// The generated rule will look like this one.
// It is now up to you to adapt this rule to check exactly 
// your needs.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that the namespace N1.N2 is not using the namespace N3.N4.N5</Name>
warnif count > 0 from n in Application.Namespaces where 
  n.IsUsing ("N3.N4.N5".AllowNoMatch().MatchNamespace()) &&
  (n.Name == @"N1.N2")
select new {
   n,
   Debt = 30.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to be warned if a particular namespace is using
// another particular namespace.
//
// Such rule can be generated for namespaces **A** and **B**:
//
// • by right clicking the cell in the *Dependency Matrix* 
// with **B** in row and **A** in column,
//
// • or by right-clicking the concerned arrow in the *Dependency 
// Graph* from **A** to **B**,
//
// and in both cases, click the menu
// **Generate a code rule that warns if this dependency exists**
//
// The generated rule will look like this one.
// It is now up to you to adapt this rule to check exactly 
// your needs.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that the assembly Asm1 is only using the assemblies Asm2, Asm3 or mscorlib</Name>
warnif count > 0 from a in Application.Assemblies where 
  ( !a.IsUsing ("Asm2".AllowNoMatch().MatchAssembly()) ||
    !a.IsUsing ("Asm3".AllowNoMatch().MatchAssembly()) ||
    !a.IsUsing ("mscorlib".MatchAssembly()) ||
     a.AssembliesUsed.Count() != 3) // Must not be used more than 3 assemblies 
&& 
  (a.Name == @"Asm1")
select new { 
   a, 
   a.AssembliesUsed,
   Debt = 30.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that a particular assembly
// is only using a particular set of assemblies.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that the namespace N1.N2 is only using the namespaces N3.N4, N5 or System</Name>
warnif count > 0 from n in Application.Namespaces where 
  ( !n.IsUsing("N3.N4".AllowNoMatch().MatchNamespace()) ||
    !n.IsUsing("N5".AllowNoMatch().MatchNamespace()) ||
    !n.IsUsing("System".MatchNamespace()) ||
     n.NamespacesUsed.Count() != 3) // Must not be used more than 3 assemblies 
                // AsmCe = Efferent Coupling for assembly
&& 
  (n.Name == @"N1.N2")
select new { 
   n, 
   n.NamespacesUsed,
   Debt = 30.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that a particular namespace
// **is only using** a particular set of namespaces.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that AsmDrawing is the only assembly that is using System.Drawing</Name>
warnif count> 0 from a in Application.Assemblies where 
   a.IsUsing ("System.Drawing".AllowNoMatch().MatchAssembly()) &&
  !(a.Name == @"AsmDrawing")
select new {
   a,
   Debt = 30.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that a particular assembly
// is **only used by** another particular assembly.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that only 3 assemblies are using System.Drawing</Name>
warnif count != 3 from a in Application.Assemblies where 
  a.IsUsing ("System.Drawing".AllowNoMatch().MatchAssembly())
select new {
   a,
   Debt = 30.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that a particular assembly
// is **only used by** 3 any others assemblies.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that all methods that call Foo.Fct1() also call Foo.Fct2(Int32)</Name>
warnif count > 0 from m in Application.Methods where 
   m.IsUsing ("Foo.Fct1()".AllowNoMatch()) &&
  !m.IsUsing ("Foo.Fct2(Int32)".AllowNoMatch())
select new {
   m,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that if a method calls a particular method,
// it must call another particular method.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that all types that derive from Foo, also implement IFoo</Name>
warnif count > 0 from t in Application.Types where 
   t.DeriveFrom ("Foo".AllowNoMatch().MatchType()) &&
  !t.Implement ("IFoo".AllowNoMatch().MatchType())
select new {
   t,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that all classes that derive from a particular base class,
// also implement a particular interface.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that all types that has the attribute FooAttribute are declared in the namespace N1.N2*</Name>
warnif count > 0 from t in 
  Application.Namespaces.WithNameWildcardMatchNotIn("N1.N2*").ChildTypes() 
  where 
    t.HasAttribute ("FooAttribute".AllowNoMatch())
select new {
   t,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that all types that are tagged
// with a particular attribute, are declared in a 
// particular namespace.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that all synchronization objects are only used from the namespaces under MyNamespace.Sync</Name>
warnif count > 0 from n in Application.Namespaces 
  where 
    (n.IsUsing ("System.Threading.Monitor".AllowNoMatch()) ||
     n.IsUsing ("System.Threading.ReaderWriterLock".AllowNoMatch()) ||
     n.IsUsing ("System.Threading.Mutex".AllowNoMatch()) ||
     n.IsUsing ("System.Threading.EventWaitHandle".AllowNoMatch()) ||
     n.IsUsing ("System.Threading.Semaphore".AllowNoMatch()) ||
     n.IsUsing ("System.Threading.Interlocked".AllowNoMatch())) 
  && !n.NameLike (@"^MyNamespace.Sync")
select new {
   n,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that all synchronization objects
// are used from a particular namespace.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
      </Group>
      <Group Name="Check Coverage on particular Code Elements" Active="False" ShownInReport="False">
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that the namespace N1.N2 is 100% covered by tests</Name>
warnif count > 0 from n in Application.Namespaces where 
  (n.Name == @"N1.N2") && 
   n.PercentageCoverage < 100
select new { 
   n, 
   n.PercentageCoverage,
   Debt = n.NbLinesOfCodeNotCovered.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This is a sample rule that shows how to check 
// if a particular namespace is 100% covered by tests.
// Both the string **@"N1.N2"** and the threshold **100** can be adapted to your own needs.
//
// To execute this sample rule, coverage data must be imported.
// More info here: http://www.ndepend.com/docs/code-coverage
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that the assembly Asm is 100% covered by tests</Name>
warnif count > 0 from a in Application.Assemblies where 
  (a.Name == @"Asm") && 
   a.PercentageCoverage < 100
select new {
   a,
   a.PercentageCoverage,
   Debt = a.NbLinesOfCodeNotCovered.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This is a sample rule that shows how to check 
// if a particular assembly is 100% covered by tests.
// Both the string **@"Asm"** and the threshold **100** can be adapted to your own needs.
//
// To execute this sample rule, coverage data must be imported.
// More info here: http://www.ndepend.com/docs/code-coverage
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that the class Namespace.Foo is 100% covered by tests</Name>
warnif count > 0 from t in Application.Types where 
  (t.FullName == @"Namespace.Foo") && 
   t.PercentageCoverage < 100
select new { 
   t, 
   t.PercentageCoverage,
   Debt = t.NbLinesOfCodeNotCovered.ToMinutes().ToDebt(),
   Severity = Severity.High
}

//<Description>
// This is a sample rule that shows how to check 
// if a particular class is 100% covered by tests.
// Both the string **@"Namespace.Foo"** and the threshold **100** 
// can be adapted to your own needs.
//
// To execute this sample rule, coverage data must be imported.
// More info here: http://www.ndepend.com/docs/code-coverage
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that the class Namespace.Foo.Method(Int32) is 100% covered by tests</Name>
warnif count > 0 from t in Application.Types where 
  (t.FullName == @"Namespace.Foo.Method(Int32)") && 
   t.PercentageCoverage < 100
select new { 
   t, 
   t.PercentageCoverage,
   Debt = t.NbLinesOfCodeNotCovered.ToMinutes().ToDebt(),
   Severity = Severity.High
}


//<Description>
// This is a sample rule that shows how to check 
// if a particular method is 100% covered by tests.
// Both the string **@"Namespace.Foo.Method(Int32)"** and the threshold **100** 
// can be adapted to your own needs.
//
// To execute this sample rule, coverage data must be imported.
// More info here: http://www.ndepend.com/docs/code-coverage
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
      </Group>
      <Group Name="Custom Naming Conventions" Active="False" ShownInReport="False">
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that all types that derive from Foo, has a name that ends up with Foo</Name>
warnif count > 0 from t in Application.Types where 
   t.DeriveFrom ("Foo".AllowNoMatch().MatchType()) &&
  !t.NameLike (@"Foo$")
select new { 
   t, 
   t.NbLinesOfCode,
   Debt = 5.ToMinutes().ToDebt(),
   Severity = Severity.Medium
}

//<Description>
// This rule is a *sample rule that can be adapted to your need*.
//
// It shows how to enforce that all classes that derive from
// a particular class, are named with a particular suffix.
//</Description>

//<HowToFix>
// This is a *sample rule* there is nothing to fix *as is*. 
//</HowToFix>]]></Query>
        <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Check that all namespaces begins with CompanyName.ProductName</Name>
warnif count > 0 from n in Application.Namespaces where 
  !n.NameLike (@"^CompanyName.ProductName")
select new { 
   n, 
   n.NbLinesOfCode,
   Debt = 10.ToMinutes().ToDebt(),
   Severity = Severity.High
} 

//<Description>
// A practice widely adopted is that, in a product source code,
// all namespaces start with "CompanyName.ProductName".
//
// This rule must be adapted with your own **"CompanyName.ProductName"**.
//</Description>

//<HowToFix>
// Update all namespaces definitions in source code to satisfy this rule.
//</HowToFix>]]></Query>
      </Group>
    </Group>
  </Queries>
  <WarnFilter>
  </WarnFilter>
</NDepend>
